Monday, March 18, 2019

Moving from PowerShell Journeyman to PowerShell Master

I’ve just finished writing another book on PowerShell. The book looked at a number of core Windows Features and components, from AD, DHCP/DNS, SMB file sharing and FSRM, Hyper, V and more. Having gone through the process of witting over 125 scripts using a dozen Windows Server 2018 features  has given me a perspective on both PowerShell in use today, and in what it takes, what you really need to know in order to progress from a Google-Engineering assisted journey man into a PowerShell  master.  There is absolutely NOTHING wrong with using Google to get the job done. And for many their career path possibly precludes acquiring deep skills. But if you are the folks who aspire, please read on!

So what do you need to know, to know how to do? The following list is not in any order:

  • Understand and be able to use the PowerShell language - the starting point, for me, is that you know the PowerShell language and can use it. You should understand the core concepts of cmdlets, objects, and the pipeline. You should be familiar the the core approach to discovery (Get-Module, Get-Command, Get-Help, and Get-Member). You need to know how each language feature works and be able to leverage it in your scripts. Knowing the internal architecture of PowerShell is also almost expected.
  • Understand the .NET Framework. Powershell is built on top of .NET – cmdlets work by using .NET. Get-Process, for example, just calls [System.Diagnostics.Process]::GetProcesses(). Also known as a static method (GetProcesses()) on a .NET Class (Systems.Diagnostics.Process). You should understand the architecture of .NET (CLR, BCL, IL and JIT Compilation, .NET Security, and more).  The .NET Framework can often provide functionality for which there are no cmdlets. For example, there a number of .NET classes useful for localisation. Time zones, clock types, DST/ST, etc are all a method call away and therefore easy to use if you know how.
  • Understand how to read C# and be able to convert C# to PowerShell. There is a feast of wonderful examples of more obscure tasks often written in C#. You should be able to read the C# sufficiently to see how the code is doing things, and be able to concert simple snippets into working PowerShell Code. Knowing enough VB.NET to convert it into PowerShell is also a useful skill.
  • Understand COM and COM objects. There are a number of features that make use of COM. The Microsoft Office products can each be automated using PowerShell’s COM interop features. The Performance Logging and Alerting subsystem makes use of COM. You use PowerShell's New-Object cmdlet to instantiate a COM object to specify PLA data collector sets.
  • Know how to use XML. Some features such as the Task Scheduler make use of XML. You should know how to use the XML emitted by windows as well as knowing how to manage XML documents and the DOM. XPath is also a useful skill. The FSRM, for example, produces reports. The report format is fixed and cannot be modified. But the FSRM also produces XML files containing the report’s raw data for you to format to your own needs. PowerShell also makes use of XML for default object formatting. which you can customise to change how PowerShell formats objects.
  • Know how PowerShell modules work. Cmdlets are delivered in modules and you can write your own. Both DSC and JEA leverage modules. You should know where modules are stores, how PowerShell finds them and how it builds the Module cache, what a manifest is.
  • JEA – Also known as Just Enough Administration. It’s a neat feature that enables you to provide delegated permissions to do just those things necessary for a person’s job and nothing more. This is a very useful security feature of Powershell that appeals to large and distributed organisations.
  • Understand how to implement DSC. DSC is a great way to configure hosts and to ensure they stay configured. You should know about DSC resources, setting up DSC pull servers (SMB and Web), and DSC reporting and error logging. You should also know how DSC resources work as well as how to write your own DSC resources)
  • Master Remoting – This is a rich topic area. You should understand the PowerShell Remoting stack (including PSRM, SOAP, WinRM), how end points work and how to create a constrained end point. 
  • Understand at Depth Core Windows Features. I suppose it’s obvious, but to be a PowerShell master you have to be able to apply your skills  to Windows. You should really understand AD (and GPO), SMB (SMB3 SOFS, Clustering and Hyper-Converged S2D), Containers and Docker, Hyper-V (and maybe VMware too!), TCP/IP Networking, Disk/FIle Storage, PLA, Task Scheduler, and probably more.
  • Leverage Azure – Organisations are increasingly moving to the cloud and knowing Azure (or AWS) is also an important skill. With Azure, you should be able to build IAAS objects in cloud including web sites, VMs, and Virtual networks. You should also be able to manage Azure Storage and Content distribution.
  • Be competent at Windows Troubleshooting – There are a variety of good PowerShell tools that assist in Troubleshooting, particularly network troubleshooting. These tools really are second nature to a PowerShell master. And to be a good trouble-shooter you really need to understand what you are troubleshooting. Knowing how to leverage the information in the event logs is also critical. You should become very familiar with  And if you ever work out how to fully automate the Windows trouble-shooters – let me know.
  • Use PowerShell Core and VSCode – PowerShell Core 6 is almost a re-invention of PowerShell. Cross-platform, open source, based on .NET Core which is also open source along with a totally new development tool (VS Code). Arguably,6.1 and 6.2 are not quite ready for hard core usage across all features. But it’s close – I am now using the developing 6.2 and VS Code in preference to the ISE and Windows PowerShell. My Grateful Dead scripts even work in PS Core! There are a number of features that do not work with PowerShell Core. Today, for example, DSC and Windows Forms are not supported (although 6.3 should support Windows.Forms!).

So a baker’s dozen of things you really need to know, and know how to do with PowerShell.

PowerShell Core and Experimental Features

In testing any new feature, one technique for getting users to use (and test) the feature is known as feature flags.  Essentially these are settings (flags) that signal you should gain access to those experimental features. The allows a user to opt-in to testing the new features. Thus is a big application, such as PowerShell, most users just use the published feature set. But if you know how, you can turn on some interesting new features. And of course if you do not like a given experimental feature, you can turn it off.  Let’s look at hot oaccess these features. In this blog post, I am using PowerShell Core 6.2.0-rc.1. If you install different versions, your mileage is going to vary!

Finding Experimental features

Finding experimental features is pretty easy. Hey – this is PowerShell and you should know what to do). Like this:

PS [C:\foo> ]> Get-ExperimentalFeature
Name                        Enabled Source   Description
----                        ------- ------   -----------
PSCommandNotFoundSuggestion   False PSEngine Recommend potential commands based on fuzzy search on a CommandNotFoundException
PSImplicitRemotingBatching    False PSEngine Batch implicit remoting proxy commands to improve performance
PSTempDrive                   False PSEngine Create TEMP: PS Drive mapped to user's temporary directory path
PSUseAbbreviationExpansion    False PSEngine Allow tab completion of cmdlets and functions by abbreviation

So these four experimental feature present on 6.2.0-rc.1 all look pretty cool to me.  The usefulness of these may vary. For me tablcompletion of cmdlet names using abbreviations could interesting. Potentialy really useful so worth looking at even though as I think about it – if the alias is any good, it’s wired into my fingers thus it may be a feature that I never use. Creating the TEMP: folder is something I would take advantage of. The PSCommandNotFoundSuggestion just helps IT Admins to find what they need. And the batching of implicit remoting commands could be very useful if you are, for example, managing Exchange On-Line  using local PowerShell and importing the session.

Enabling Experimental Features

Again – this is PowerShell so: Simples:

PS [C:\foo> ]> Get-ExperimentalFeature | Enable-ExperimentalFeature
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell.
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell.
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell.
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell.

So very simple to add in. Due to how these features are implemented you nee to restart Pwsh before you can access the fetures:

Using Experimental Features:

The Command not found suggestion feature is nice. After enabling, PowerShell does a better job of handling typos, like this:

PS [C:\foo> ]> get-chliditem
get-chliditem : The term 'get-chliditem' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ get-chliditem
+ ~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (get-chliditem:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Suggestion [4,General]: The most similar commands are: Get-ChildItem, Get-ChildItem2.

Nice.  It could be really useful where you have long cmdlet names

Disabling Experimental Features

Needless to say, disabling them is simple too: Use the DisableExperimentalFeature cmdlet to disable the commands.


Experimental features are PowerShell Core features that may or may not be added to future versions of PowerShell Core. They are easy to enable, consume, and disable as you wish but use at your own risk.

Thursday, March 07, 2019

Setting up DHCP in Windows Server 2019

In my recently published book (Windows Server 2019 Automation with PowerShell), I included several recipes to show how to install DHCP, how to setup a scope, and how to setup DHCP load balancing and fail over. This blog post looks at the steps involved.

In this walk through, I assume you have two servers on which you wish to run DHCP. Many smaller organisations install DHCP on their DCs for simplicity – I’m assuming the two servers are DC1.Reskit.Org and DC2.Reskit.Org. You also need to determine what IP addresses to hand out (this sample uses the rante, the subnet mask (, and an IP address for the DHCP Server.

Hree are the steps:

1. Install DHCP Service on DC1, DC2

# Create a script block
$SB1 = {
  # Install the service
  Install-WindowsFeature -Name DHCP -IncludeManagementTools
  # Add the DHCP server's security groups
  # Let DHCP know it's all configured
  $RegHT = @{
    Path  = 'HKLM:\SOFTWARE\Microsoft\ServerManager\Roles\12'
    Name  = 'ConfigurationState'
    Value = 2  }
  Set-ItemProperty @RegHT
# Run the script block on DC1, DC2
Invoke-Command –Computer DC1 –ScriptBlock $SB1
Invoke-Command –Computer DC2 –ScriptBlock $SB1
# Authorise the DHCP server in AD
Add-DhcpServerInDC -DnsName DC1.Reskit.Org
Add-DhcpServerInDC -DnsName DC2.Reskit.Org
# Restart the DHCP Service on DC1, DC2
$SB2 = {
  Restart-Service -Name DHCPServer –Force
Invoke-Command –Computer DC1 –ScriptBlock $SB2
Invoke-Command –Computer DC2 –ScriptBlock $SB2

2. Create a DHCP Scope

# Add new DHCP Scope to DC1
$SHT = @{
  Name = 'Reskit'
  StartRange   = ''
  EndRange     = ''
  SubnetMask   = ''
  ComputerName = 'DC1.Reskit.Org'
Add-DhcpServerV4Scope @SHT

3. Configure DHCP Server Options

# Set DHCP V4 Server Option Values
$OHT = @{
  ComputerName = 'DC1.Reskit.Org'
  DnsDomain    = 'Reskit.Org'
  DnsServer    = ''
Set-DhcpServerV4OptionValue @OHT

4. Configure Fail Over/Load Balancing between DC1 and DC2

$FHT = @{
  ComputerName       = 'DC1.Reskit.Org'
  PartnerServer      = 'DC2.Reskit.Org'
  Name               = 'DC1-DC2'
  ScopeID            = ''
  LoadBalancePercent = 60
  SharedSecret       = 'j3RryIsG0d!'
  Force              = $true
Add-DhcpServerv4Failover @FHT

After you complete these two steps, both DC1 and DC2 are able to satisfy DHCP configuration requests on the 10.10.10/0 subnet, can provide some options to DHCP clients along with offered IP address and the subnet mask, and is in a fail over/load balancing relationship.

Monday, March 04, 2019

It's Done! So now what??

Last week, I completed work on a new PowerShell book. The book is entitled Windows Server 2019 Automation with PowerShell. The front cover looks like this:

One of the more interesting features the more eagle-eyed viewers might notice is that Jeffrey Snover wrote a forward. I've known Jeffrey for a very long time and admire him enormously. The draft of his foreword reads like this:

Of course, I love it and am immensely flattered. I just hope the book lives up to his introduction.

The book contains over 120 'recipes' - small scripts that do useful things. I have tried to strip out some of the overhead normally associated with production scripting (error handling, logging, firewalls, etc.) to concentrate on the essence of the various features and how to manage them with PowerShell. The scripts are also published on Github at

I learned a lot in the process of writing this book. It was fun delving down into various aspects of Windows Server 2019 and playing with various features. Being able to log performance data then graph it all in a few lines of code was neat.

A major resource in writing this latest book was This is Microsoft's (largely) open-source documentation platform. The documents are, in the main, of an excellent standard. And when I found a page that has an error or was unclear - I just fixed it. Highly satisfying to improve the documentation.

The book is now available on Amazon: