Monthly Archive

Categories

PowerShell

PowerShell templating systems

Code reuse is a big plus when you’re developing lots of scripts. The ability to create templates for your code can also save you lots of time – for instance when advanced functions first appeared I create myself a template the included all of the validation checks, the code to switch functionality based on parameter sets and code to handle –whatif and –confirm.  Things have moved on since then and there are a number of PowerShell templating systems.

 

Plaster – https://github.com/PowerShell/Plaster

 

PSScaffold – https://github.com/RedeployAB/PSScaffold

 

PowerShell template - https://github.com/kayasax/PowershellTemplate

 

Check them out – one or more maybe the thing you need or they may inspire you to create something better.

PowerShell Trim

PowerShell Trim – no its not a new slimming fad. Trimming is the act of removing characters – usually white space – from the beginning or end of a string.

You have three methods on the String class you can use

Trim
TrimEnd
TrimStart

 

PS> $str = "   abcdefghijk   "
PS> $str.TrimStart()
abcdefghijk
PS> $str.TrimEnd()
abcdefghijk
PS> $str.Trim()
abcdefghijk

 

You can also trim specific characters from the beginning or end of a string

PS> $str = ".,:abcdefghijk:,."

PS> $tc = [char]'.', [char]',', [char]':'

 

PS> $str.TrimStart($tc)
abcdefghijk:,.
PS> $str.TrimEnd($tc)
.,:abcdefghijk
PS> $str.Trim($tc)
abcdefghijk

 

You should now be able to handling any string trimming required in your code

PowerShell editors

PowerShell works great when you use it interactive;y but at some point you’re likely to want to write substantial pieces of code – scripts or functions – for which you’ll need an editor. This is my take on PowerShell editors.

 

There are PowerShell add-ins for Visual Studio – one of the best is PowerShell Tools by Adam Driscoll: https://marketplace.visualstudio.com/items?itemName=AdamRDriscoll.PowerShellToolsforVisualStudio2017-18561

 

If you’re working with Visual Studio already and need to add PowerShell to your project then this is a good option. if you’re only creating PowerShell code then Visual Studio has too much overhead.

 

PowerShell ISE (Integrated Scripting Environment) was introduced with PowerShell v2. Its gone through a number of updates with subsequent versions of PowerShell. It’s the tool I normally use. It supplies access to the debugger and happily runs across a number of PowerShell runspaces. You can use it to run and debug code on remote machines.

 

ISEs drawback is that its Windows only and it isn’t part of PowerShell v6.

 

As far as I can tell all of the editor related development work is going into VSC (Visual Studio Code) https://code.visualstudio.com/. VSC is a lightweight editor like ISE but can also work with a large number of other languages. You can tailor VSC by only downloading those extensions you need. I have extensions for PowerShell, JSON, XML MSSQL, markdown and Docker among others.

 

VSC has good debugging tools. I do miss the ability to run selected lines of code like ISE. I’ll be sticking with ISE for demos for now.

 

VSC has the advantage that its available for Windows and Linux (and mac) so you can use the same editor cross platforms if need be.

 

There are other products you can consider. ISE Steroids (from the PowerShell studio) is a great add-in for ISE. Sapien have tools such as PowerShell Studio and Primal Script. Idera have PowerShell Plus. These and other tools have to be paid for.

 

So what editor should you use.

 

ISE is great for Windows only environments. If you need cross-platform or multi-language consider VSC.

 

I use ISE but I’m increasingly turning to VSC as that seems to be getting the development effort and evolving very quickly with updates most months.

Call for topics closing 1 October

The call for topics is closing 1 October at 23:59 GMT. We’ve had a fantastic set of submissions. Creating an agenda for the 2018 Summit is going to be very difficult because we’ve had so many fantastic sessions submitted and I don’t have enough slots to  take them all.

 

The call for topics is hosted by papercall.io – highly recommended – and the cut off is automatic.

 

I WILL NOT ACCEPT ANY SESSIONS SUBMITTED AFTER THE CUT OFF DATE.

DSC–the future?

I was incredibly excited when I first saw DSC – it was in April 2013 as a special MVP only preview at the first PowerShell Summit – as a work in progress. Since that time my excitement has waned to the point that I now ask DSC – the future?

 

Looking at the PowerShell Team announcement about the introduction of DSC core - https://blogs.msdn.microsoft.com/powershell/2017/09/12/dsc-future-direction-update/

I have to question if a complete new version of DSC is worth my time investigating especially when backward compatibility isn’t guaranteed.

 

Don Jones has question where DSC is going - https://powershell.org/2017/09/13/the-future-of-powershells-desired-state-configuration/

 

Overall, I’d say that DSC has had a mixed success since its introduction due to changes and the difficulty around preforming some activities. The integration with Azure hasn’t been smooth.

Is it time to look at another configuration tool set. Microsoft’s  current rush to embrace Linux may make Chef or Puppet a better option for you. Read the comments on the PowerShell Team announcements to see what other people think about DSC.

PowerShell comments

Putting comments into your code has been a long established practice – this is how you do PowerShell comments

A single line comment is indicated by the # symbol

# This is a comment
Get-Process

 

You can put a comment at the end of a line but not in the middle. Once you’ve added a comment that’s it for the rest of the line

Get-Process    # This is a comment

In ISE and Visual Studio Code comments are shown in green by default

 

You can also create multi-line comments

<#
This is
a multi-line
comment
#>
Get-Process

 

Be careful if you use # symbols in file names or other data in PowerShell – you may end up with PowerShell thinking you’ve declared a comment

Splitting multiline string

Saw an interesting question on splitting multiline string

If you get a set of strings

item1
item2
item3

emailed to you then you could put them in a text file and use Get-Content to read them into an array. The question was could you paste them into PowerShell and get the same effect.

Not sure if this is the easiest way but it works

PS> $x  = @'
item1
item2
item3
'@ -split "`n"

PS> $x.length
3

PS> $x[0]
item1

PS> $x[1]
item2

PS> $x[2]
item3

PowerShell books DoD

A number of my PowerShell books including PowerShell in Action and PowerShell in Depth will be part of Manning’s Deal of the Day on 29 September 2017

Use code dotd092917au at http://bit.ly/2hzetVX

For DoD details see  https://www.manning.com/dotd

Write text to a file with Powershell

PowerShell is all about working with objects but sooner or later you’ll need to write text to a file with Powershell.

You have two options. The *-Content cmdlets and Out-File

PS> Get-Command *-Content

CommandType     Name 
 -----------     ---- 
 Cmdlet          Add-Content 
 Cmdlet          Clear-Content 
 Cmdlet          Get-Content 
 Cmdlet          Set-Content


 PS> Get-Command *-File

CommandType     Name 
 -----------     ---- 
 Cmdlet          Out-File 
 Cmdlet          Unblock-File

Lets start with Out-File

Out-File simply sends output to a file. Its the equivalent of the redirection operator but with parameters.

PS> Get-Process -Name power* | Out-File -FilePath gp1.txt 
 PS> Get-Content gp1.txt

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
 -------  ------    -----      -----     ------     --  -- ----------- 
    672      33   124272     144548       1.88   6112   1 powershell 
    767      31    86756     105336       2.64  11984   1 powershell

Whatever comes down the pipeline is redirected to the specified file instead of being displayed on screen.

By default Out-File (like redirection) will overwrite an existing file. You can append data to the file

PS> Get-Process -Name power* | Out-File -FilePath gp1.txt -Append 
 PS> Get-Content gp1.txt

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
 -------  ------    -----      -----     ------     --  -- ----------- 
    672      33   124272     144548       1.88   6112   1 powershell 
    767      31    86756     105336       2.64  11984   1 powershell

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
 -------  ------    -----      -----     ------     --  -- ----------- 
    673      33   124272     144580       1.88   6112   1 powershell 
    798      32    73980      92564       2.64  11984   1 powershell

To protect an existing file that you don’t want overwriting IF it exists use the –NoClobber parameter

PS> Get-Process -Name power* | Out-File -FilePath gp1.txt -NoClobber 
 Out-File : The file 'C:\test\gp1.txt' already exists. 
 At line:1 char:28 
 + Get-Process -Name power* | Out-File -FilePath gp1.txt -NoClobber 
 +                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo          : ResourceExists: (C:\test\gp1.txt:String) [Out-File], IOException 
    + FullyQualifiedErrorId : NoClobber,Microsoft.PowerShell.Commands.OutFileCommand

You can overwrite a read only file with the –Force parameter.

By default Out-File uses unicode encoding. Other encodings are available

Unknown
String
Unicode
BigEndianUnicode
UTF8
UTF7
UTF32
ASCII
Default
OEM

This will be important if the file will be read by something other than PowerShell.

The *-Content cmdlets are different in that they expect strings

PS> Get-Process -Name power* | Set-Content -Path gp2.txt 
 PS> Get-Content -Path gp2.txt 
 System.Diagnostics.Process (powershell) 
 System.Diagnostics.Process (powershell)

Set-Content and Add-Content use ASCII encoding by default. The other encodings are available

ASCII Uses the encoding for the ASCII (7-bit) character set.
BigEndianUnicode Encodes in UTF-16 format using the big-endian byte order.
BigEndianUTF32 Encodes in UTF-32 format using the big-endian byte order.
Default Encodes using the default value: ASCII.
Byte Encodes a set of characters into a sequence of bytes.
String Uses the encoding type for a string.
Unicode Encodes in UTF-16 format using the little-endian byte order.
UTF7 Encodes in UTF-7 format.
UTF8 Encodes in UTF-8 format.
Unknown The encoding type is unknown or invalid; the data can be treated as binary.

We can modify our previous  example

PS> Get-Process -Name power* | Out-String | Set-Content -Path gp2.txt 
 PS> Get-Content -Path gp2.txt

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
 -------  ------    -----      -----     ------     --  -- ----------- 
    627      34   156396     177492       3.00   6112   1 powershell 
    726      32    71640      91540       3.17  11984   1 powershell

Set-Content will overwrite the content of a file or create a new file. Add-Content appends data to a file

PS> Get-Process -Name power* | Out-String | Add-Content -Path gp2.txt 
 PS> Get-Content -Path gp2.txt

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
 -------  ------    -----      -----     ------     --  -- ----------- 
    627      34   156396     177492       3.00   6112   1 powershell 
    726      32    71640      91540       3.17  11984   1 powershell


 Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
 -------  ------    -----      -----     ------     --  -- ----------- 
    676      34   156436     177648       3.05   6112   1 powershell 
    744      32    71604      91540       3.27  11984   1 powershell

The help files for these cmdlets show so other examples.

NOTE: In PowerShell v6 the encodings will be standardised.

PowerShell string concatenation

Strings -  a list of characters such as ‘abcd’ – are a common feature of programming or scripting. Sometimes you need to join – concatenate – two or more strings together. This is how PowerShell string concatenation works.

First you need to know that strings can be defined with single quotes or double quotes:

PS> $sq = 'A single quoted string'
PS> $sq
A single quoted string

PS> $dq = "A double quoted string"
PS> $dq
A double quoted string

The difference is that you can substitute into a double quoted string. Best practice is to use single quotes UNLESS you intend to substitute into the string

PS> 'I am $sq'
I am $sq
PS> "I am $sq"
I am A single quoted string

String concatenation can be performed using the concatenation operator – a plus sign or through string substitution

PS> $s1 = 'abcd' + 'defg'
PS> $s1
abcddefg

You can use variables

PS> $s1 = 'abcd'
PS> $s2 = 'defg'
PS> $s3 =  $s1 + $s2
PS> $s3
abcddefg

When you concatenate strings like this you’re actually creating a new string not extending an existing one.

Alternatively, use string substitution

PS> $s4 = "$s1$s2"
PS> $s4
abcddefg