Modifying hashtables

Saw a question about modifying hashtables. The suggested code seemed like overkill.

The starting point is this hashtable:

$record = @{Name=’Joe’; Date=’2019-02-01′; Status=’Pending’}

The updated data is:
$update = @{Name=’Joe’; Date=’2019-04-01′; Status=’Hired’; City=’York’; Country=’England’}

You need to keep the Name and Date from $record. Modify the Status to be that of $update and add the City and County information to record.

Changing status is a simple assignment:

$record.Status = $update.Status

Adding the City and County information is done by adding them to the original hashtable.

$record += @{City=$update.City; Country=$update.Country}

You can check the results by displaying the hashtable.

Technically, you’re creating a new hashtable, adding the information from $record and then the City and Country information but as it stays in the original variable its always referred to as modifying.

Advertisements
Posted in Powershell | Leave a comment

PowerShell SSH

PowerShell SSH support is available by default in PowerShell v6.0 and later. The big thing for PowerShell v6.0 was SSH based remoting.

On Windows 10 / Server 2019 OpenSSH is available as an optional install. On earlier versions of Windows you need to install OpenSSH – https://github.com/PowerShell/openssh-portable

The installation instructions are available at

https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH

If you’re still using Windows PowerShell and need SSH support consider

https://github.com/darkoperator/Posh-SSH

I think SSH remoting should be considered a must learn as its ideal for non-domain remoting situations and avoids the need for certificates in non-domain scenarios.

Posted in Powershell | Leave a comment

Count

Count is a property on arrays

PS> $x = 1..10
PS> $x.Count
10

The same information is available through Length (which is the property in the System.Array class definition)

PS> $x.Length
10

If the variable is a scalar you get 1 returned

PS> $x = 1
PS> $x.Count
1

With an empty array you get zero returned

PS> $x = @()
PS> $x.Count
0

This means that however many items are in the array you can safely check the number of items.

Be careful with strings as Count and Length give different results

PS> $x = ‘asdfghjkl;’
PS> $x.count
1
PS> $x.length
10

If you want to test  the number of elements returned use Count rather than length

Posted in Powershell | 1 Comment

Where-Object options

You have a few Where-Object options when you want to filter data.  Remember that Where-Object filters objects based on property values and Select-Object filters objects based on object position in the pipeline or array as well as filtering properties.

The classic way to use Where-Object is to use a filter script

PS> Get-Process | Where-Object -FilterScript {$_.CPU -gt 5}

You’re filtering to accept process objects where the CPU property shows more than 5 seconds of usage

As an aside most people don’t use the FilterScript parameter they rely on positional parameters to assign the script block to FilterScript.  Script analysers such as PSScriptAnalyzer (at least as far as the rules in VScode are concerned) don’t seem to object to the use of positional parameters in this case which is rather sloppy and remiss. Another reason I don’t like any of the analysis tools I’ve tried as they aren’t consistent.

PowerShell then introduced a simpler syntax

PS> Get-Process | Where-Object -Property CPU -gt -Value 5

which is usually used via positional parameters

PS> Get-Process | Where-Object CPU -gt 5

which again seems to sneak past the analysers.  If you want multiple clauses in the filter using –and / –or to join them you have to use the original syntax.  Also note that –gt isn’t an operator – its a parameter!

The is also the little used array method option to filter a collection of objects

PS> (Get-Process).Where({$_.CPU -gt 5})

which it should be noted is much faster than Where-Object on the pipeline.

When using Where-Object remember the options and if you’re using positional parameters remember what you’re actually doing.

Posted in Powershell | Leave a comment

Opposing Automation

Opposing Automation – no I don’t mean that you should oppose it. The sad fact is that there are very many administrators opposed to automation.

Within two hours of starting my last job I was told by my team lead “you’ll never automate anything here”. Needless to say our relationship never really worked after that. I ended up in a different team and yes I did automate a lot of stuff.

Other all time favourites of mine are:

“We’re too busy to automate”

“We’ve always done it this way”

If you meet real roadblocks like this you’ll more than likely end up looking for another job.

There are a few things you can try though.

In your own work try automating tasks that take a long time and very repetitive for example one company insisted on the event logs being checked for specific events on a regular basis. Now, the idea solution would be a monitoring solution but that means spending money…  One solution is to RDP into all the boxes and query the event logs.  On the other hand a quick script that remotes into the required servers and checks the logs. Report the date and time of the events by server and you’re done. Better still schedule the task for overnight and you don’t need to do much at all once its set up.  Even if you have to create the functionality in chunks its surprising how quickly you can build up to a useful set of utilities. Don’t forget – automate what you need not what the books (including mine) suggest – you’re the one how knows what you need.

The other approach that can sometimes work is to find how you can help someone else get something done. Again you may need to build the functionality in chunks but getting other people to sell the benefits of automation will be a big help.

However, you approach the problem there will always be people opposed to automation – your only options are to work round them or to move somewhere where your ideas are appreciated. Don’t stay and suffer – its not worth it.

Posted in Philosophy, Powershell | 1 Comment

File rename

File rename is a topic that seems to keep recurring.

The simple answer is that you use Rename-Item

PS> Rename-Item -Path C:\test\Newoutdata01.txt -NewName OldData01.txt

If for whatever bizarre reason you have a character such as [ in your file name the rename won’t work

PS> Rename-Item -Path C:\test\New[outdata02.txt -NewName OldData02.txt
Rename-Item : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard character pattern is not valid: New[outdata02.txt
At line:1 char:1
+ Rename-Item -Path C:\test\New[outdata02.txt -NewName OldData02.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Rename-Item], ParameterBindingException
+ FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.RenameItemCommand

The way round that is to use –LiteralPath

PS> Rename-Item -LiteralPath C:\test\New[outdata02.txt -NewName OldData02.txt

If you need to rename a bunch of files use Get-ChildItem and pipe the results into Rename-Item

Posted in Powershell | Leave a comment

What’s new in PowerShell v6.2

The What’s new in PowerShell v6.2 is available at – https://docs.microsoft.com/en-gb/powershell/scripting/whats-new/what-s-new-in-powershell-core-62?view=powershell-6 – together with the already existing documents for PowerShell v6.0 and v6.1.

Its worth reading through the three documents – one each for v6.0, v6.1 and v6.2 to see the whole range of changes in PowerShell core.

Posted in PowerShell v6 | Leave a comment