PowerShell for Windows Admins


December 12, 2018  7:42 AM

Find duplicate characters in a string

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Staying with our current theme of manipulating strings this is how you find duplicate characters in a string.

 

Convert the string to a char array, group on the characters and use Where-Object to filter the characters that occur more than once – the duplicates. Sort the output for easier viewing.

December 11, 2018  10:42 AM

Join-String

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Join-String is a new cmdlet in PowerShell v6.2 preview 3. Join-String enables you to use the pipeline to join strings.

We’ve had the –join operator for a long time:

PS>  1..3 -join ‘,’
1,2,3

 

As an alternative you could do

PS>  1..3 | Join-String -Separator ‘,’
1,2,3

 

You can add a prefix and suffix to the final string:

PS>  1..3 | Join-String -OutputPrefix ‘A’ -OutputSuffix ‘b’ -Separator ‘,’
A1,2,3b

 

You can use the property of objects on the pipeline as a source for the data:

PS>  Get-ChildItem -Path C:\Scripts\Techniques\ | select -ExpandProperty Basename | Join-String -Separator ‘,’
arrays,numbertechniques,stringtechniques

 

Quotes – single or double – can be added

PS>  Get-ChildItem -Path C:\Scripts\Techniques\ | select -ExpandProperty Basename | Join-String -Separator ‘,’ -SingleQuote
‘arrays’,’numbertechniques’,’stringtechniques’

PS>  Get-ChildItem -Path C:\Scripts\Techniques\ | select -ExpandProperty Basename | Join-String -Separator ‘,’ -DoubleQuote
“arrays”,”numbertechniques”,”stringtechniques”

 

The current culture can also be use to influence the string. For instance dates:

PS>  Get-Date

11 December 2018 16:25:43

PS>  Get-Date | Join-String
12/11/2018 16:25:52

 

To me the string version of the date reads  12 November 2018 not 11 December 2018 so I need to use my culture

PS>  Get-Date | Join-String -UseCulture
11/12/2018 16:26:54

 

And now it looks correct.

I suspect that Join-String will become one of those cmdlet that has many, many uses. For instance an easy way to create sequential file names:

PS>  1..5 | foreach {$_ | Join-String -OutputPrefix ‘File’ -OutputSuffix ‘.txt’}
File1.txt
File2.txt
File3.txt
File4.txt
File5.txt


December 11, 2018  5:23 AM

PowerShell v6.2 preview 3 install issue

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

PowerShell v6.2 preview 3 install issue – PowerShell v6.2 preview 3 is now available from https://github.com/PowerShell/PowerShell/releases but you may notice a probloem if you install over the top of PowerShell v6.2 preview 2.

 

When you click on the icon to start preview 3 the console will flash open and then immediately close.

 

The fix is to either uninstall preview 2 before installing preview 3 OR install preview 3 over the top of preview 2 and immediately rerun the preview 3 installation selecting the repair option. The install will work through and then PowerShell v6.2 preview 3 will work.

 

The underlying cause is understood and hopefully will be fixed in a later release


December 6, 2018  9:12 AM

Count the occurrence of given character in a string

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Last time I showed how to get the number of occurrences of each character in a string but how do you count the occurrence of given character in a string?

 

You use one of the fundamental concepts on which PowerShell is built – its composability. In other words PowerShell is composed of a lot of very small pieces of code that each do its own job and you select and assemble the components  you need to complete a given task.

 

What that boils down to is that you already have a function that counts the number of occurrences of a character in a string. Rather than writing another function, or spending time modifying your existing function, see if you use other PowerShell cmdlets (or functions) help you get the result you need. In this case:

PS> measure-occurrence -teststring  ‘cwfhgfhcdsgfchgfegfegfkvcnfdhvjewy\dfsa’ | where Name -eq ‘s’

Count Name
—– —-
2 s

 

Gives you the result you want without any further work.

 

Two ways to use the function makes it more cost effective to write.


December 5, 2018  10:22 AM

Count occurrence of characters in a string

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

How do you count occurrence of characters in a string?

Group-object is a ready made cmdlet to answer this question

 

 

Split the string into a character array. Pipe into group-object using –NoElement to drop the data and sort the results in descending order.


November 30, 2018  6:00 AM

Test if string contains numeric

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

How can you test if a string contains a numeric character?

The simple answer is to use a regular expression.  If you’ve been reading my stuff for any length of time you’ll know how much I love regular expressions. This is a simple regex.

Create a string

PS>  $s1 = ‘qwertyuiop’

Test if it has numerics

PS>  $s1 -match ‘\d’
False

if you use D you’re testing for non numeric characters
PS>  $s1 -match ‘\D’
True

Lets add a numeric to confirm

PS>  $s2 = ‘qwert6yuiop’
PS>  $s2 -match ‘\d’
True

This time we get a positive result

The test for non numerics still works
PS>  $s2 -match ‘\D’
True


November 29, 2018  1:01 PM

Reverse a string

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I sort of brushed over it on my last post but this is how you reverse a string.

The code is at https://github.com/RichardSiddaway/Blogcode/blob/master/stringtechniques.ps1

Take the input string and turn it into an array of chars. Use the reverse static method of the array class to reverse the array. Other useful array methods can be found in the documentation – https://docs.microsoft.com/en-us/dotnet/api/system.array?redirectedfrom=MSDN&view=netframework-4.7.2

-Join is used to stitch the reversed char array back into a string.


November 28, 2018  1:49 PM

Test if a string is a palindrome

Tom Curtin Tom Curtin Profile: Tom Curtin
Powershell, PowerShell Scripts, String

This is the first in a short series in which I’ll look at some string handling techniques. PowerShell is all about objects but sometimes you just have to work with the basics. In this post I’ll show how to test in a string is a palindrome.
A palindrome is a list of characters that read the same backwards as well as forwards. Radar is a word that is the same when reversed for example – its a simple palindrome. You can have phrases that are palindromes as well.

function test-palindrome {
[CmdletBinding()]
param (
[string]$teststring
)
Write-Verbose -Message “Input string: $teststring”
$cr = $teststring.ToCharArray()

$ca = $cr | where {$_ -match ‘\w’}

$clnstring = -join $ca
Write-Verbose -Message “Clean string: $clnstring”
[array]::Reverse($ca)
$revstring = -join $ca
Write-Verbose -Message “Reversed string: $revstring”
## make test case insensitive
if ($revstring -ieq $clnstring){
$true
}
else {
$false
}
}

 

There isn’t a method on the string class to reverse a string so convert the string to an array of chars then use Where-object to filter out non-word characters e.g. punctuation. Recreate the input string without the punctuation etc then use the Reverse static method on the array class. Use –join to create the reversed string from the char array. Use –ieq (force case insensitive comparison) to test if the two strings are equal and return true or false accordingly.

Some simple examples:
PS> test-palindrome -teststring radar
True
PS> test-palindrome -teststring Radar
True
PS> test-palindrome -teststring Richard
False

And testing a phrase:
PS> test-palindrome -teststring “Madam, I’m Adam” -Verbose
VERBOSE: Input string: Madam, I’m Adam
VERBOSE: Clean string: MadamImAdam
VERBOSE: Reversed string: madAmImadaM
True
PS> test-palindrome -teststring ‘The fat cat sat on the mat’
False


November 27, 2018  6:44 AM

Third way to find pairs for given sum

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

There’s a third way to find pairs for given sum that’s a bit more complicated.

function get-pairs2 {
[CmdletBinding()]
param (
[int[]]$iarray,

[int]$value
)

$sarray = $iarray | Sort-Object

Write-Information -MessageData “Array: $iarray” -InformationAction Continue
Write-Information -MessageData “Sorted Array: $sarray” -InformationAction Continue
Write-Information -MessageData “Sum: $value” -InformationAction Continue

$left = 0
$right = $sarray.Count – 1

while ($left -lt $right){
Write-Verbose -Message “left = $left  right =$right”
$sum = $sarray[$left] + $sarray[$right]

if ($sum -eq $value){
Write-Information -MessageData “Pair to give sum: ($($sarray[$left]), $($sarray[$right]))” -InformationAction Continue
$left += 1
$right -= 1
}
elseif ($sum -lt $value) {
$left += 1
}
elseif ($sum -gt $value){
$right -= 1
}
}
}

 

In this technique start by sorting the array. I’ve sorted it ascending which is the default.

 

Set the initial counters to the start and end of the sorted array. Use the while loop to work through the array. Sum the array elements and test if the sum equals the required value – if it does print the results and increment the left counter and decrement the low counter (move them closer together).

 

If the sum is less than the required value increment the left counter and if its more decrement the right counter.

 

Eventually the counters will meet, the right counter will be greater than the left counter and the loop will finish.

 

This technique takes a bit of thinking about so this is a run with the counter values printed

PS> get-pairs2 -iarray $iarray -value 7 -Verbose
Array: 1 8 3 -3 6 4 9 5 10 2
Sorted Array: -3 1 2 3 4 5 6 8 9 10
Sum: 7
VERBOSE: left = 0  right =9
Pair to give sum: (-3, 10)
VERBOSE: left = 1  right =8
VERBOSE: left = 1  right =7
VERBOSE: left = 1  right =6
Pair to give sum: (1, 6)
VERBOSE: left = 2  right =5
Pair to give sum: (2, 5)
VERBOSE: left = 3  right =4
Pair to give sum: (3, 4)

 

Next time we’ll start to  look at some string handling techniques


November 26, 2018  9:11 AM

A more elegant way to find pairs

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Last time I showed a brute force way to find the pairs of numbers in an array that would sum to a given value. This time I have a more elegant way to find pairs.

 

function get-pairs1 {
[CmdletBinding()]
param (
[int[]]$iarray,

[int]$value
)

Write-Information -MessageData “Array: $iarray” -InformationAction Continue
Write-Information -MessageData “Sum: $value” -InformationAction Continue

foreach ($n in $iarray){
$target = $value – $n

if ($target -in $iarray) {
Write-Information -MessageData “Pair to give sum: ($n, $target)” -InformationAction Continue
}
}
}

 

Iterate through the array and for each element subtract the element from the required value. Test to see if this result is a member of the array and print out the pair if it is.

 

This has the advantage of printing the pair each way so for an example array

Array: 1 8 3 -3 6 4 9 5 10 2

 

You’ll get

Pair to give sum: (1, 6)

and

Pair to give sum: (6, 1)


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: