Monthly Archive

Categories

Monthly Archives: August 2018

PowerShell v6.0.4

PowerShell v6.0.4 is available from https://github.com/PowerShell/PowerShell/releases

 

From the release notes it appears to be just a fix to the mac installer and consolidation of the Nuget packages.

 

This is the second update to PowerShell v6.0 within a month. If you have a lot machines with v6.0 installed you need to think about automating the installation as you don’t get a patch but a complete new install package with each set of fixes.

Create a directory with PowerShell

I was recently asked how you can create a directory with PowerShell

Using the command prompt you’d do this

c:\Scripts> md c:\Test0908

c:\Scripts>dir c:\test*
Volume in drive C has no label.
Volume Serial Number is DAA0-D709

Directory of c:\

09/07/2018 11:20 <DIR> test
09/08/2018 15:22 <DIR> Test0908
01/11/2017 11:59 <DIR> TestCIM
01/03/2018 13:36 <DIR> testmodule
25/04/2018 21:33 <DIR> TestScripts
0 File(s) 0 bytes
5 Dir(s) 147,528,462,336 bytes free

 

The same is true of PowerShell

PS> md c:\test090801

Directory: C:\

Mode   LastWriteTime    Length Name
----   -------------    ------ ----
d----- 09/08/2018 15:23        test090801


PS> dir c:\test*

Directory: C:\

Mode   LastWriteTime        Length Name
----   -------------        ------ ----
d----- 09/07/2018 11:20            test
d----- 09/08/2018 15:22            Test0908
d----- 09/08/2018 15:23            test090801
d----- 01/11/2017 10:59            TestCIM
d----- 01/03/2018 12:36            testmodule
d----- 25/04/2018 21:33            TestScripts

 

However, md is an alias of mkdir

PS> Get-Command md

CommandType Name
----------- ----
Alias       md –> mkdir

 

If you dig into mkdir you’ll find that its a function

PS> Get-Command mkdir

CommandType Name
----------- ----
Function    mkdir

 

Looking into the definition of the mkdir function

PS> Get-Command mkdir | select -expand Definition

you’ll see that it uses New-Item. The actual code that does the work is:

$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('New-Item',
[System.Management.Automation.CommandTypes]::Cmdlet)
$scriptCmd = {& $wrappedCmd -Type Directory @PSBoundParameters }
$steppablePipeline = $scriptCmd.GetSteppablePipeline()
$steppablePipeline.Begin($PSCmdlet)

 

The important parts are that its using New-Item with a type of Directory

This leads to using New-Item directly

PS> New-Item -Path C:\ -Name Test090802 -Type Directory


Directory: C:\


Mode   LastWriteTime      Length Name
----   -------------      ------ ----
d----- 09/08/2018 15:36          Test090802

 

or

PS> New-Item -Path C:\Test090803 -Type Directory


Directory: C:\


Mode   LastWriteTime      Length Name
----   -------------      ------ ----
d----- 09/08/2018 15:36          Test090803

 

I always prefer to give the parent path and the name as it’s a more explicit statement of what I’m doing.

One thing to note is that you can create the whole path to a nested folder in one pass:

PS> New-Item -Path C:\Test090804\test090805 -Type Directory


Directory: C:\Test090804


Mode   LastWriteTime      Length Name
----   -------------      ------ ----
d----- 09/08/2018 15:38          test090805

 

The command creates test090804 and then test090805 as a subfolder of test090804.

In case you were wondering dir is an alias of Get-ChildItem

PS> Get-Alias dir

CommandType Name
----------- ----
Alias       dir -> Get-ChildItem

Think outside the box

One of PowerShell’s great strengths is that there are often a number of ways to achieve the same endpoint. It’s also a great weakness as newcomers are confused as to which approach to adopt and “experts” will tell you that you should only use approach X. You need to think outside the box sometimes.

 

Last time I used summing the contents of an array to demonstrate the speed of various options.

 

There is another way to sum an array:

1..1000 | Measure-Object -Sum | select -ExpandProperty Sum

 

If you measure the speed its about the same as foreach method

PowerShell speed

I’ve read and heard a lot about PowerShell speed recently – that is the speed of execution of your scripts and how you can make your code faster.

 

The first thing to think about – and this is the one many people miss – is does the absolute speed of my PowerShell code actually matter. If I have a script that takes 5 seconds to run and it takes me 10 days effort to get that script to run in 4 seconds is that a worthwhile use of my time? If the script runs once in a while – definitely not. If it runs 1000s of times a day then probably yes.

 

The other thing to consider is what else you could be doing in that 10 days. You could probably solve a few problems that would save a bunch of time.

 

My working definition of a good script is one that works, runs in an acceptable time frame and is readable for relatively easy maintenance. Code style and anything else is just fluff.

The bit that got me thinking was the difference in speed between:

$i = 0
1..1000 | foreach {$i += $_}
$i

and

$i = 0
foreach ($j in 1..1000) {$i += $j}
$i

 

We actually discuss this in PowerShell in Action. The pipeline is optimised for resource usage. The foreach command is optimised for speed. You have a trade off between resource usage and speed – congratulations you’re a programmer and have to make decisions about how your code will run.

 

What wasn’t mentioned was a third option – the foreach method

$i = 0
(1..1000).foreach({$i += $_})
$i

 

I don’t see the foreach (or where) method used very much but its always worth keeping at the back of your mind

I decided to run some tests

Measure-Command -Expression {

$i = 0
1..1000 | foreach {$i += $_}
$i

} | select TotalMilliseconds

Measure-Command -Expression {

$i = 0
foreach ($j in 1..1000) {$i += $j}
$i

} | select TotalMilliseconds

Measure-Command -Expression {

$i = 0
(1..1000).foreach({$i += $_})
$i

} | select TotalMilliseconds

 

I found that using the foreach loop was 2-4 times faster than using foreach-object on the pipeline.

 

The foreach method was about 2 times faster than foreach-object.

 

Testing your code for speed isn’t an exact science but some simple tests using measure-object can give you some interesting data.

Keynote at PS Day 2018

PSDay is one day PowerShell conference in London. I’m proud, and honoured, to have been asked to provide the Keynote at PS Day 2018.

 

Full details of the event are available at https://psday.uk/

 

I’ll also be doing a session on CIM.

 

It looks like a really good agenda.

 

Looking forward to the event and hope to see you there