PowerShell for Windows Admins


November 4, 2016  10:03 AM

Working with multiple CIM objects

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, WMI

Many of the CIM objects we work with in our computers come in multiple instances – disks and network cards are a couple of examples. Many times when you see examples you’ll see something like this:

$disks = Get-WmiObject -Class Win32_LogicalDisk

foreach ($disk in $disks){
if ($disk.Size -gt 0) {
$disk | select DeviceId,
@{N=’Free’; E={[math]::Round($disk.FreeSpace/1GB, 2)}},
@{N=’Size’; E={[math]::Round($disk.Size/1GB, 2)}},
@{N=’PercUsed’; E={[math]::Round((($disk.Size – $disk.FreeSpace) / $disk.Size) * 100, 2)}}
}
}

Get a collection of objects. Iterate through them with foreach and do something.

You can, and should, do this as a pipeline operation. The code above is really a hangover from VBScript coding.

Converting the above to a pipeline gives

Get-WmiObject -Class Win32_LogicalDisk |
where Size -gt 0 |
foreach {
$_ | select DeviceId,
@{N=’Free’; E={[math]::Round($_.FreeSpace/1GB, 2)}},
@{N=’Size’; E={[math]::Round($_.Size/1GB, 2)}},
@{N=’PercUsed’; E={[math]::Round((($_.Size – $_.FreeSpace) / $_.Size) * 100, 2)}}
}

NOTE – before anyone starts complaining yes I know you can use a  filter on Get-WmiObject I’m explaining the principle! Also, I know that you could go straight into the select on the pipeline but if you want to add extra processing e.g. send an email if the disk is more than 80% used you need the foreach

You can do similar things with NICs for example

Get-WmiObject -ClassName Win32_PerfFormattedData_Tcpip_NetworkInterface |
where CurrentBandwidth -gt 0 |
foreach {

$props = [ordered]@{
Name = $psitem.Name
Computer = $psitem.PSComputerName
PercUtilisation = (($psitem.BytesTotalPersec * 8) / $psitem.CurrentBandWidth) * 100
}

New-Object -TypeName PSObject -Property $props

} |
where PercUtilisation -gt 0.5 |
foreach {
$text =  @”
$($_.Name) on $($_.Computer)

Bandwidth utilized:  $($_.PercUtilisation) %
“@

$text

}

Rather than displaying $text send an email if the utilisation is too big.

where PercUtilisation -gt 0.5

is used so I actually get to see results. You probably want 60% or more on your production machines.

November 3, 2016  9:00 AM

New Hyper-V switch on Windows 10

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Hyper-V, Windows 10

My test/lab machine had been running Windows Server 2016 TP 5. With Server 2016 now RTM it was time for a rebuild.  Unfortunately, 2016 RTM carried on from TP5 and decided not to work with my wireless card.

Decided to try using Hyper-V on Windows 10 – it recognises the wifi card and is happy to work with it.

After installing the Hyper-V feature I needed to create some Hyper-v virtual switches

PS> New-VMSwitch -SwitchType External -Name ‘LAN’ -NetAdapterName ‘LAN’
New-VMSwitch : Cannot validate argument on parameter ‘SwitchType’. The argument “External” does not belong to the set
“Internal,Private” specified by the ValidateSet attribute. Supply an argument that is in the set and then try the
command again.
At line:1 char:26
+ New-VMSwitch -SwitchType External -Name ‘LAN’ -NetAdapterName ‘LAN’
+                          ~~~~~~~~
+ CategoryInfo          : InvalidData: (:) [New-VMSwitch], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.HyperV.PowerShell.Commands.NewVMSwitch

But External is a valid switch type

PS> New-VMSwitch -SwitchType x
New-VMSwitch : Cannot bind parameter ‘SwitchType’. Cannot convert value “x” to type
“Microsoft.HyperV.PowerShell.VMSwitchType”. Error: “Unable to match the identifier name x to a valid enumerator name.
Specify one of the following enumerator names and try again:
Private, Internal, External”
At line:1 char:26
+ New-VMSwitch -SwitchType x
+                          ~
+ CategoryInfo          : InvalidArgument: (:) [New-VMSwitch], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.HyperV.PowerShell.Commands.NewVMSwitch

Wonder how many of these issues I’m going to find!


October 31, 2016  10:52 AM

Don’t reinvent the wheel

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell, Windows Server

Way back when I used to take Microsoft certification exams there were often questions of the form “Perform task X with the minimum of administrative effort” Most, if nor all, of the possible answers would be correct but the correct answer was the one that achieved the goal with the minimum amount of work.

Many, if not most, administrators don’t seem to follow that model.

This was brought home to me when I saw a forum discussion about collecting event log information from a bunch of remote servers on a regular basis.

You could set up a scheduled task/job that runs a script against the remote servers – collects the  log information and populates an Excel spreadsheet

OR

You could enable event log forwarding and just interrogate the combined logs as needed.

The second option is the easier to MAINTAIN and will cost you less effort in the long run.

When you start to solve a problem – stop and search for a bit to see if there is a solution already available in Windows server. Bet you’ll be surprised by what you find


October 31, 2016  10:38 AM

Start and end dates

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Be careful with start and end dates when search for files or through event logs.  Often people want to see what happened yesterday

If you do this

PS> $end =  Get-Date
PS> $start = (Get-Date).AddDays(-1)
PS> $start

30 October 2016 16:32:35
PS> $end

31 October 2016 16:32:16

And you get the last 24 hours

if you really want just yesterday you need to create the exact dates and times

PS> $start = Get-Date -Day 30 -Month 10 -Year 2016 -Hour 00 -Minute 00 -Second 00
PS> $end = Get-Date -Day 31 -Month 10 -Year 2016 -Hour 00 -Minute 00 -Second 00
PS> $start

30 October 2016 00:00:00
PS> $end

31 October 2016 00:00:00

I know there are easier ways but using Get-Date shows exact;y what’s happening and is simple


October 31, 2016  10:13 AM

Registration opens 1 November

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Registration for the 2017 PowerShell Summit opens tomorrow – 1 November 2016

First come first served. The agenda and registration are available here – https://eventloom.com/event/home/summit2017


October 28, 2016  1:37 AM

Upgrading WSL

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Ubuntu, Windows 10

If you start  WSL (Bash on Ubuntu on Windows) and see messages like this:

7 packages can be updated.
1 update is a security update.
root@RSsurfacePro2:~#

You can view the available updates:

root@RSsurfacePro2:~# apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [95.7 kB]
Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [94.5 kB]
Get:4 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [160 kB]
Get:5 http://security.ubuntu.com/ubuntu xenial-security/main Translation-en [65.8 kB]
Get:6 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [415 kB]
Get:7 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [51.9 kB]
Get:8 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 Packages [1,176 B]
Get:9 http://archive.ubuntu.com/ubuntu xenial-updates/main Translation-en [159 kB]
Get:10 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [356 kB]
Get:11 http://archive.ubuntu.com/ubuntu xenial-updates/universe Translation-en [128 kB]
Get:12 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse amd64 Packages [5,492 B]
Fetched 1,532 kB in 35s (42.9 kB/s)
Reading package lists… Done

And to install the updates use:

apt-get upgrade


October 25, 2016  4:02 AM

PowerShell and DevOps Global Summit 2017 agenda

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The agenda for next year’s Summit is almost complete – we’ve notified all speakers as to whether their sessions have been accepted or not. If you haven’t received your notification please check your spam/junk mail.

We have a small number of sessions yet to publish – mainly around possible focus groups on the Wednesday afternoon.

To view the agenda go to the Summit event site – from https://powershell.org/summit/ click on the Brochure and registration link.

Registration opens 1 November 2016.


October 25, 2016  3:01 AM

PowerShell 10th Anniversary

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

If you were in the audience at the 2006 Microsoft European TechEd (or IT Forum or whatever they called it that year) key note presentation you’ll know that 14 November 2016 is the 10th anniversary of PowerShell.

The Powershell team is presenting a day long event on 14th November to commemorate the anniversary.

Initial announcement is here https://blogs.msdn.microsoft.com/powershell/2016/10/24/join-the-powershell-10th-anniversary-celebration/

More details to follow


October 19, 2016  10:48 AM

PowerShell Summit 2017–agenda

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

We’re finalising the agenda for the 2017 Summit. Most of the sessions are now up on the event site. Go to https://powershell.org/summit/ and click the Brochure and Registration link. You’ll be able to down load a brochure describing next years Summit and view the proposed agenda (it is subject to change with no notice).

Registration opens 1 November 2016


October 18, 2016  2:07 PM

Server Uptime

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, WMI

Its easy to get the last boot time of a Windows machine but how do you get the uptime

function Get-Uptime {
[CmdletBinding()]
param (
[string]$ComputerName = $env:COMPUTERNAME
)

$os = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $ComputerName

$uptime = (Get-Date) – $os.LastBootUpTime

$uptime

}

Use Get-CimInstance to get the Win32_OperatingSystem class. To calculate the uptime subtract the value of LastBootTime from the current time and date.

You’ll get a Timespan object returned.

PS> Get-Uptime
Days              : 1
Hours             : 10
Minutes           : 32
Seconds           : 26
Milliseconds      : 838
Ticks             : 1243468385381
TotalDays         : 1.4391995201169
TotalHours        : 34.5407884828056
TotalMinutes      : 2072.44730896833
TotalSeconds      : 124346.8385381
TotalMilliseconds : 124346838.5381

Pick out whichever properties you need for your report


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: