header image

Archive for PowerShell

What do you use PowerShell for?

Posted by: | December 27, 2019 Comments Off on What do you use PowerShell for? |

What do you use PowerShell for?


Personally, I’ve always used it as a tool to automate the administration of Windows systems. I’ve created and managed systems. Managed the OS and file system. Administered Exchange, Active Directory and SQL Server amongst other tasks.


I’ve also used PowerShell for a wide variety of other tasks – searching emails for information about a particular event; creating server and network documentation for audit purposes – the ability to write output directly to word documents is a huge time saver.


I’ve also used PowerShell for other purposes – solving maths puzzles, calculating the effective temperature (wind chill) and the change in temperature with altitude for instance.


I’ve seen numerous demos of a GUI front end on PowerShell code though the concept has never really appealed to me.


Cross platform administration is potentially in reach with PowerShell 6/7 but what’s the real audience for that?


So, what do you use PowerShell for?

under: PowerShell

Season’s Greetings

Posted by: | December 24, 2019 Comments Off on Season’s Greetings |

Season’s Greetings from PowerShell

(77,101,114,114,121,32,67,104,114,105,115,116,109,97,115,32,97,110,100,32,97,32,72,97,112,112,121,32,78,101,119,32,89,101,97,114 | foreach {[char][byte]$psitem}) -join ”

under: PowerShell

PowerShell remoting

Posted by: | December 24, 2019 Comments Off on PowerShell remoting |

PowerShell remoting must be every administrators favourite feature. The fact that you can connect to to multiple machines and get your tasks done just makes life so much easier.


PowerShell remoting originally appeared in PowerShell v2. In v1 Get-WMIObject was the only cmdlet capable of connecting to a remote machine. Remoting used WSMAN for inter-machine connectivity. This has advantages and disadvantages. The advantages are that its router friendly the disadvantage that PowerShell remoting over WSMAN ties authentication to the Kerberos protocol used in Active Directory. This means that remoting is easy within the domain but become harder to work with outside of the domain environment. You should use certificates for authentication outside the domain. There are other ways but you should use certificates for WSMAN remoting authentication outside the domain.


Windows PowerShell v3-v5.1 saw many cmdlets have a computername parameter added – for instance the Process and Service cmdlets. In these cases DCOM/RPC is used for the connectivity. This can have problems with routers and firewalls. Individual cmdlet remoting has been removed in PowerShell v6/v7 so isn’t recommended.


PowerShell v6 saw the introduction of SSH based remoting for connecting to non-Windows machines – it also works Windows to Windows. WSMAN is available on Linux but isn’t fully supported and isn’t recommended. SSH isn’t easy to set up. Its getting better but still not as straight forward as WSMAN. Use SSH remoting for Windows – Linux. SSH is also great in a non-domain scenario.


Windows 10 / Server 2016 saw the introduction of PowerShell Direct (Windows PowerShell and PowerShell core both support PowerShell Direct). If your local machine is the Hyper-V host you can remote over the VMbus to virtual Windows machines on the host.


Lots of options for remoting. Recommendations:

Windows-Windows within the domain – use WSMAN

Windows-Linux (or vice versa) or Windows to Windows outside the domain use SSH

If you’re on the Hyper-V host use PowerShell direct for Windows VMs

under: PowerShell

PowerShell cmdlets

Posted by: | December 19, 2019 Comments Off on PowerShell cmdlets |

Continuing my series of the features in PowerShell we shouldn’t forget – we get to PowerShell cmdlets.


The PowerShell cmdlet ecosystem has grown from the 137 cmdlets in PowerShell v1 to who knows how many are available to windows PowerShell v5.1, PowerShell v6.x and PowerShell v7 – certainly in the thousands.


A cmdlet is a small piece of code that does one job. The PowerShell concept is that cmdlets are linked into a pipeline to perform a particular task. PowerShell cmdlets emit .NET objects which are passed between cmdlets on the pipeline.


So far so good. More cmdlets available means more tasks can be performed with a single command. When I wrote PowerShell in Practice (v1/v2 times) there wasn’t such great cmdlet coverage so you had to resort to scripting. These days many, if not most, of things we had to write scripts for can now be done with cmdlets.


Cmdlets come from a number of sources:

– In the box with PowerShell

– Cmdlets provided by other Microsoft teams that ship in Windows

– Cmdlets provided by other Microsoft products

– Cmdlets provided by third party software vendors

– Cmdlets from public sources such as the PowerShell gallery


Some of the PowerShell v6/v7 is being provided through the gallery or being trialled in the gallery before, possibly, moving into the product.

So far so good.


On Windows we have a huge set of cmdlets such that I can say I’ve been using PowerShell since it was still Monad (much cooler name) and there are cmdlets I’ve not had reason to use.


This was true as of Windows PowerShell v5.1. PowerShell v6 was initially disappointing because it couldn’t utilise a significant set of the existing cmdlets suite. Porting of cmdlets to run under PowerShell v6 and the WindowsCompatibility module (a delicious irony that Windows needs a compatibility module to enable the use of functionality developed for Windows) whose functionality has since moved into Windows v7 have done much to address the issue. The vast majority of the functionality available under Windows PowerShell v5.1 is now available under PowerShell v7 though gaps still exist.


On Linux and mac the picture isn’t so rosy. There are the cmdlets that are available in the PowerShell v6/v7 install and as far as I’m aware that’s about it. Roughly back to where we were with PowerShell v1/v2. With Windows PowerShell we had the capability of falling back to CIM (WMI), COM or .NET to get things done. CIM and COM aren’t available on non-Windows and PowerShell v6/v7 are built on .NET core which introduces some limitations. To me if PowerShell is to be a true cross-platform administration tool I need to be able to issue the same command – irrespective of platform – and get the job done. Until we get cmdlets to work with storage, network adapters, IP addresses etc etc etc we’re not really in a cross-platform scenario.


Cmdlets are good. More cmdlets are better. Cross-platform cmdlets would be ideal.

under: PowerShell

PowerShell Pipeline

Posted by: | December 18, 2019 Comments Off on PowerShell Pipeline |

With PowerShell v7 getting close to being finished I thought it might be time to look at some of the longstanding PowerShell features that may get taken for granted with the concentration on newer features. Starting point is the PowerShell Pipeline.


The pipeline is one of the fundamental features of PowerShell. In some respects its strongest feature. The ability to link commands together into a pipeline is not new, or unique, to PowerShell but what is unique is what’s passed along the pipeline. Traditional shells pass text output between commands – PowerShell passes .NET objects.


Well, to be 100% accurate PowerShell passes .NET objects that have a wrapper. The wrapper may, or may not, modify the object. Properties, and methods, can added or hidden.


Irrespective of its actual form – and for many purposes you can actually ignore the modifications PowerShell makes – you’re still working with .NET objects.


One of the design goals of PowerShell was to make it composable. Small pieces of code (cmdlets) are linked together (the pipeline) to supply the answer to a problem. For instance:

PS> Get-Process | Sort-Object CPU -Descending | Select-Object -First 5


You fetch the processes, sort by their CPU usage (highest first) and select the top 5 CPU users.

Three simple commands linked in a pipeline give a much more sophisticated outcome.


I can remember writing VBScript code to discover which users in a 12,000 seat Active Directory had Outlook Web Access (OWA) enabled. It took 78 lines of code. When the Exchange cmdlets became available it was a single pipeline.


Much has been made recently of the fact that the pipeline is slow. It may not be the fastest way to get something done but a PowerShell pipeline is easy to understand and maintain than some of the alternatives that are coming into the language.


The PowerShell pipeline may be one of the oldest features in PowerShell but its still one of the strongest and most defining features. If that changes then its probably time to look for an alternative.

under: PowerShell

Fibonacci series

Posted by: | November 23, 2019 Comments Off on Fibonacci series |

Today’s date 23 November is 1123 id written as month then day. Those numbers are the start of the Fibonacci series. So as its Fibonacci day here’s a quick PowerShell function to create a Fibonacci series.


function new-fibonacci {
param (
[int]$numberofelements = 10

## first 2 elements

$ell1 = 1

$ell2 = 1

$i = 2
while ($i -lt $numberofelements){
$elnext = $ell1 + $ell2

$ell2 = $ell1
$ell1 = $elnext




The function has 1 parameter which determines the number of elements of the series you want to produce.


The first two elements are hard coded as being equal to 1 and output from the function.


The bulk of the work is done in the while loop – deliberately chosen to test at the top of the loop.


The next element in the series is the sum of the current last and next to last elements. The counter is incremented, the current last element becomes the next to last and the newly calculated element becomes the current last element.


If you just want the numbers displayed

PS> new-fibonacci


will display the first ten elements

To get a specific number of elements

PS> new-fibonacci -numberofelements 17


If you want the numbers in an array for further processing

PS> $fib = new-fibonacci -numberofelements 17



under: PowerShell


Posted by: | October 31, 2019 Comments Off on Resolve-Path |

Resolve-Path is a cmdlet I haven’t used much – if at all – so I thought I should have a look at it.

At an arbitrary point in the file system:

PS> Get-Location



.. Indicates the next level up

PS> Get-ChildItem -Path ..

Directory: C:\Scripts\Modules



..\.. indicates two levels up

PS> Get-ChildItem -Path ..\..

Directory: C:\Scripts



Resolve-Path will resolve any use of wildcards and other characters with meaning into the full path

PS> Resolve-Path -Path ..



PS> Resolve-Path -Path ..\..



Note that

PS> Resolve-Path -Path .



is effectively the same as Get-Location

under: PowerShell

Ad hoc development

Posted by: | October 31, 2019 Comments Off on Ad hoc development |

I was having a discussion about how people can learn PowerShell at the recent UK PowerShell day and mentioned ad hoc development. Surprisingly, no-one really knew what I meant.


Ad hoc development is a concept more than a development type. It was used extensively back in the days of PowerShell v1 and v2 but seems to have dropped off the radar these days.


Many people seem to learn the PowerShell language – either from a class or a book – but then don’t have any idea how to put that into practice. This is a failing of our teaching methods. Too many times I’ve seen people asking for help because they’ve dived into trying to create huge complicated scripts, or modules, and don’t have the background knowledge or experience to actually get the code to work.


Ad hoc development is one approach to moving from a basic knowledge of the PowerShell language to coding production level scripts and modules.


The starting point is the command line and working interactively. Use individual cmdlets or even a pipeline of cmdlets. If you find you’re using the same pipeline a lot then save as a script. Later, as you learn more you can parameterise the script, add all the production bells and whistles and even turn it into a module.


PowerShell is a huge beast these days with many parts you probably don’t need to start with. Use what you need now and add to your code as you learn rather then trying to jump right into a big complicated project. In the long run you’ll learn faster and end up getting more done with less frustration.

under: PowerShell

Hidden files

Posted by: | October 13, 2019 Comments Off on Hidden files |

If you suspect there are hidden files in a folder you can use the Attributes parameter to discover them:

PS> Get-ChildItem -Path c:\test -Attributes H


PS> Get-ChildItem -Path c:\test -Attributes h


PS> Get-ChildItem -Path c:\test -Hidden


If you want to see all files irrespective of them being hidden use Force

PS> Get-ChildItem -Path c:\test –Force


which will also show system files.

There are a number of ways to make a file hidden but the most generic is:

PS> Get-ChildItem -Path C:\test\Newoutdata03.txt | ForEach-Object {$_.Attributes += ‘Hidden’}


You can modify the criteria used to define the files passed into Foreach-Object by using the path, filter, exclude or include parameters of Get-ChildItem. The Hidden attribute is set while preserving the other attributes.

To remove the Hidden attribute:

PS> Get-ChildItem -Path C:\test\ -Hidden | ForEach-Object {$_.Attributes -= ‘Hidden’}


The Hidden attribute is removed whilst preserving other attributes. The files passed into ForEach-Object can again be filtered with the Get-ChildItem parameters.

under: PowerShell

Receive-Job Keep parameter

Posted by: | September 29, 2019 Comments Off on Receive-Job Keep parameter |

The Receive-Job Keep parameter is required if you want the data contained in the job to remain available. if you don’t use the –Keep parameter (a switch) the data will be deleted.


Its a pain to remember to use the Keep parameter. I’ve been working with jobs a lot just recently and the number of times I had to rerun jobs because I forgot to use Keep doesn’t bear thinking about.


I finally got round to adding it to the default parameter values.

This line in my profile

$PSDefaultParameterValues = @{‘Install-Module:Scope’=’AllUsers’; ‘Update-Module:Scope’=’AllUsers’; ‘Receive-Job:Keep’ = $true}


ensures I won’t forget ever again. Because Keep is a switch you have to set the value to true.

under: PowerShell

« Newer Posts - Older Posts »