PowerShell for Windows Admins


December 30, 2016  2:10 PM

Preserving property order

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

This is a very common pattern:

$os = Get-CimInstance -ClassName Win32_OperatingSystem 
$comp = Get-CimInstance -ClassName Win32_ComputerSystem

$props = @{
  OS = $os.Caption
  InstallDate = $os.InstallDate
  LastBoot = $os.LastBootUpTime
  Make = $comp.Manufacturer
  Model = $comp.Model
}

New-Object -TypeName PSObject -Property $props

Get some data – in this case a couple of WMI classes and create an output object.

Unfortunately, the output looks like this

Make        : Microsoft Corporation
Model       : Surface Pro 2
LastBoot    : 30/12/2016 09:41:52
OS          : Microsoft Windows 10 Pro Insider Preview
InstallDate : 08/12/2016 13:20:04

The property order is NOT preserved because you’re working with a hash table. If you absolutely have to preserve the property order use an ordered hash table

$os = Get-CimInstance -ClassName Win32_OperatingSystem 
$comp = Get-CimInstance -ClassName Win32_ComputerSystem

$props = [ordered]@{
  OS = $os.Caption
  InstallDate = $os.InstallDate
  LastBoot = $os.LastBootUpTime
  Make = $comp.Manufacturer
  Model = $comp.Model
}

New-Object -TypeName PSObject -Property $props

All you do is add [ordered] in front of the hashtable definition and your output becomes

OS          : Microsoft Windows 10 Pro Insider Preview
InstallDate : 08/12/2016 13:20:04
LastBoot    : 30/12/2016 09:41:52
Make        : Microsoft Corporation
Model       : Surface Pro 2

exactly what you defined

December 29, 2016  2:52 PM

Linux on the desktop

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Linux, Windows 10

My sense of humour has some quirky moments – as my friends will tell you. Last night I had a lot of time to sit and think (why is a story for another time and place) and it one point a thought about Linux on the desktop struck me.

Back in the 1980s when I worked in seismic exploration and desktop computers were emerging I remember seeing articles at least once every year that “this is the year that Unix takes over the desktop”

This then morphed to “this is the year that Linux takes over the desktop”

Of course neither of these fantasies were actually likely to happen – and I’m deliberately ignoring the Mac OS which is unix based.

However, my thought yesterday was that *nix on the desktop is actually a reality. Windows 10 includes the Bash on Ubuntu on Windows option which brings the bash shell to Windows.

Bet this way of getting *nix on the desktop was ever envisaged. Smile


December 27, 2016  5:28 AM

Inertia rules

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Opinion, Powershell

In this article https://powershell.org/2016/12/15/the-key-to-understanding-powershell-on-windows-or-linux/ Don Jones explains Windows administrators have difficulty explaining, and “selling” PowerShell to Linux admins.

I’ve known Don for quite a long time and He’ll be the first to tel we don’t agree on everything so It’ll be no surprise to learn that I disagree with parts of his argument.

I also think he’s missed one of the major factors – INERTIA!

Inertias can be defined, among other ways,  as a tendency to do nothing or remain unchanged. This is a property of a great many admins I’ve met usually wrapped around the phrase – “but we’ll always done it this way”

Inertia is a major governor in the Windows space with the majority of admins still not embracing PowerShell and automation – I’ve even heard “We’re too busy to automate” as an excuse.

People resist change. PowerShell represents change so its resisted. Inertia is being overcome in the Windows space and I suspect PowerShell will expand into the Linux space but not quickly. Linux admins have spent a long time learning to use their toolset and that inertia  isn’t going to be overcome quickly.

A few iterations of PowerShell through the open source and you might begin to see some traction. Until then inertia rules.


December 22, 2016  1:54 PM

Applying updates through WSUS

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, Windows Server 2016, WMI

I like to keep the virtual machines in my test lab up to date so have a WSUS server to download and manage updates. The difficulty is applying the updates. With Windows 2012 R2 I used a module that would contact the WSUS server and apply the updates – the was especially useful on server core installations.

I found with Windows 2016 that this COM based module wasn’t reliable so after a bit of investigation discovered that there are some CIM classes that you can use to discover and apply available updates and see what updates have been applied.

All I need is a simple set of code so wrote a bare bones module that offers three functions:

#Scan for available updates
function Get-AvailableUpdate {
  [CmdletBinding()]
  param()
  $ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession  
  $result = $ci | Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=0";OnlineScan=$true}
  $result.Updates
}

#Install all available updates
function Install-AvailableUpdate {
  [CmdletBinding()]
  param()
  $ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession
  Invoke-CimMethod -InputObject $ci -MethodName ApplyApplicableUpdates
}

#list installed updates
function Get-InstalledUpdate {
  [CmdletBinding()]
  param()
  $ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession
  $result = $ci | Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=1";OnlineScan=$true}
  $result.Updates
}

Testing so far seems to be good. As this is just for me I’m bothering with adding error testing or other production ready stuff. This works and I’ll fix problems as they occur


December 20, 2016  2:20 PM

Calculating Standard Deviation – the class

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

You’ve seen how to calculate standard deviation and how to turn that calculation into a PowerShell function. This time we’ll use the calculation to create a class:

class stats {
  
  static [double] StandardDeviation ([double[]]$numbers) {

    $mean = $numbers | Measure-Object -Average | select -ExpandProperty Average
    $sqdiffs = $numbers | foreach {[math]::Pow(($psitem - $mean), 2)}

    $sigma = [math]::Sqrt( ($sqdiffs | Measure-Object -Average | select -ExpandProperty Average) )
    
    return [math]::Round($sigma, 3)
    
  }
}

Name the class stats. We’ll create a static method on the class that will calculate the Standard Deviation. The method takes an array of doubles as input – integers are converted automatically to double.

The calculation is the same as before. Just add the return keyword to ensure you actually get the output. Using return is mandatory in PowerShell classes.

Because its a static class you don’t need to create an instance of the class – just use it directly:

$numbers = 1..10
[stats]::StandardDeviation($numbers)
[stats]::StandardDeviation(1..10)


December 20, 2016  10:00 AM

Calculating Standard Deviation – the function

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Last time I showed how to calculate the standard deviation of a set of numbers and said the code could easily be turned into a function

function Measure-StandardDeviation {
  [CmdletBinding()]
  param (
    [double[]]$numbers
  )
  $mean = $numbers | Measure-Object -Average | select -ExpandProperty Average
  $sqdiffs = $numbers | foreach {[math]::Pow(($psitem - $mean), 2)}

  $sigma = [math]::Sqrt( ($sqdiffs | Measure-Object -Average | select -ExpandProperty Average) )
  [math]::Round($sigma, 3)
}

I’ve called the function Measure-StandardDeviation based on Measure-Object producing the mean.

The parameter is set to accept an array of doubles – floating point numbers – integers will be automatically converted to doubles.

To use the function

$numbers = 1..10
Measure-StandardDeviation -numbers $numbers
or create the input array directly
Measure-StandardDeviation -numbers (1..10)


December 19, 2016  3:08 PM

Calculating Standard Deviations–the calculation

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

A while ago I saw something asking about calculating standard deviations for a set of numbers in PowerShell. You can calculate the mean (average) of a set of numbers using Measure-Object

 $numbers = 1..10

$mean = $numbers | Measure-Object -Average | select -ExpandProperty Average
$mean
5.5

To calculate the standard deviation you:

Subtract the mean of the set from each number in the set and square the difference. Then calculate the mean of those squared differences and finally take the square root of the result.

We already have the mean

so lets calculate the differences and square them

$sqdiffs = $numbers | foreach {[math]::Pow(($psitem - $mean), 2)}

The Pow static method of the math class is used to create the squares. The standard deviation (normally referred to as sigma) is calculated:

$sigma = [math]::Sqrt( ($sqdiffs | Measure-Object -Average | select -ExpandProperty Average) )
[math]::Round($sigma, 3)

You can calculate the mean of the squares of the differences using measure-object again. I used the Round static method of the math class to give my answer 3 decimal places.

Now that we can calculate the standard deviation we could turn this into a method, or a PowerShell class or even create a proxy function for Measure-Object that enables you to calculate standard deviation.


December 17, 2016  2:22 PM

Christmas treat

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Books, Hyper-V

If you’re looking for something to treat yourself for Christmas then garb a copy of My new book – Learn Hyper-V in a Month of Lunches.

Better still tomorrow 18 December 2016 you can get the book for half price:

Deal of the Day December 18: Half off Learn Hyper-V in a Month of Lunches. Use code dotd121816au at http://bit.ly/2hOkhKb


December 14, 2016  5:38 AM

Active Directory Schema Versions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

With the release of Windows Server 2016 its time to update my schema versions script

$sch = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySchema]::GetCurrentSchema()
$de = $sch.GetDirectoryEntry()
switch ($de.ObjectVersion) {
    13{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2000"; break}
    30{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2003"; break}
    31{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2003 R2"; break}
    44{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2008"; break}
    47{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2008 R2"; break}
    56{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2012"; break}
    69{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2012 R2"; break}
    87{"{0,25} " -f "Schema Version $($de.ObjectVersion) = Windows 2016"; break}
    default{"{0,25} {1,2} " -f "Unknown Schema Version", $($de.ObjectVersion); break}
}

The script uses the GetCurrentSchema static method on System.DirectoryServices.ActiveDirectory.ActiveDirectorySchema. Derives a directory entry and uses the ObjectVersion to determine the corresponding Windows Server version.


November 30, 2016  3:52 PM

Conference–time to book

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Registration is open for the PowerShell Summit (USA) and PowerShell Conference (Europe). Now is an excellent time to decide which one you’re going to attend next year. If you’re serious about PowerSHell you should be at one of these events.

PowerShell Summit – https://eventloom.com/event/home/summit2017

PowerShell Conference – http://www.psconf.eu/


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: