PowerShell for Windows Admins

October 25, 2014  10:16 AM

PowerShell 5.0 – – classes

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve shown this method of creating a new object several times:

$source = @”
public class LastBoot
public string ComputerName {get; set;}
public string LastBootime {get; set;}

Add-Type -TypeDefinition $source -Language CSharpVersion3

$computer = $env:COMPUTERNAME

$props = [ordered]@{
ComputerName = $computer
LastBootime = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer |
select -ExpandProperty LastBootUpTime

New-Object -TypeName LastBoot -Property $props

Define a class in C# – in this case a simple class that has 2 properties ComputerName and LastBootime which are both strings for simplicity. Compile the code via Add-Type

Define the value of the properties in a hash table and create an object.

This approach has a number of benefits – you have given your object a distinct type so you can easily create format and type data for it. Also the properties are strongly typed which means if to try to define a property with a value that isn’t of the correct type or can’t be converted into the correct type the creation will fail.

The drawbacks are that you have to use C# to define the class and Add-Type won’t let you redefine the class in the PowerShell session in which you create it.

The drawbacks, especially the first one, put most people off from using this approach.

PowerShell 5.0 has simplified working like this as you can now create classes directly in PowerShell.

class LastBoot {

$obj = [LastBoot]::new()

$obj.ComputerName = $env:COMPUTERNAME
$obj.LastBootime = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer |
select -ExpandProperty LastBootUpTime


Use the class keyword to start the class definition. The properties are defined in a similar way to advanced functions – note there isn’t a comma after the function.

A new instance is created like this:

$obj = [LastBoot]::new()

You can’t use New-Object in the latest version of PowerShell 5.0  – I presume that will be added at some time.

You can then populate the properties and output the object.

This is just scratching the surface with classes. This whole addition will make working with new objects more flexible as you can easily define what you want your output object to be like and then PowerShell will enforce the property types for you.

In case you were wondering use LastBootime was deliberate

October 25, 2014  3:13 AM

PowerShell 5 – zip and unzip

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One the extras in PowerShell 5.0 is a couple of cmdlets for working with zip archives. Actually, you’ll find they are PowerShell advanced functions if you look in the module which you’ll find at C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive

You get 2 cmdlets:

£> Get-Command *archive | ft CommandTYpe, Name -a

CommandType Name
———– —-
Function Compress-Archive
Function Expand-Archive

To compress

$files = Get-ChildItem -Path C:\Scripts -Filter *.csv | select -ExpandProperty Fullname
Compress-Archive -Path $files -DestinationPath C:\Scripts\t1.zip -CompressionLevel Optimal

or a single file

Compress-Archive -Path c:\scripts\test.csv -DestinationPath C:\Scripts\t2.zip -CompressionLevel Optimal

To uncompress

Expand-Archive -Path C:\Scripts\t1.zip  -DestinationPath c:\scripts

if you need to overwrite files:

Expand-Archive -Path C:\Scripts\t1.zip  -DestinationPath c:\scripts -Force

October 22, 2014  2:39 PM

Run with PowerShell

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Came across  something new today – Run with PowerShell.

If you have PowerShell 3.0 or later installed – right click on your script and select “Run with PowerShell”

A few rules though – The script can’t take parameters or output anything to the prompt. You can’t interact with the script or the console window.

Execution policy is set to Bypass – not sure I like that idea  – unless the ExecutionPolicy is Allsigned in which case only signed scripts can be run this way.  See about_Run_With_PowerShell for more details

October 22, 2014  11:59 AM

DSC for Exchange

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A series of posts on using the Exchange DSC resources – starts here


October 20, 2014  10:42 AM

Upgrading PowerShell

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The Scripting Guy has started a series on upgrading the version of  PowerShell you run.

My article in the series is out today – http://blogs.technet.com/b/heyscriptingguy/archive/2014/10/20/should-i-upgrade-to-latest-windows-powershell-version.aspx

October 18, 2014  1:49 PM

DSC Resource Kit Wave 8 coming?

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Looks like the next wave of the DSC resource kit is on its way – a set of resources for Exchange 2013 have been published – https://gallery.technet.microsoft.com/office/xExchange-PowerShell-1dd18388 with a wave 8 tag.

I’ve been waiting for the Exchange resources – they’re going to make my life so much easier.

October 15, 2014  11:44 AM

Default formatting

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

If you run get-process you will see something like this for each process

£> Get-Process | select -f 1

Handles NPM(K) PM(K) WS(K) VM(M)  CPU(s)   Id ProcessName
——- —— —– —– —–  ——   — ———–
80      7   960  4096    44         1560 armsvc

You’ll get the same display if you use

£> Get-Process | select -f 1 | ft

If you ask for a list – you get something different

£> Get-Process | select -f 1 | fl
Id      : 1560
Handles : 80
CPU     :
Name    : armsvc

Looking at all of the data for a single process give you this:

£> Get-Process | select -f 1 | fl *
__NounName                 : Process
Name                       : armsvc
Handles                    : 80
VM                         : 46186496
WS                         : 4194304
PM                         : 983040
NPM                        : 7136
Path                       :
Company                    :
CPU                        :
FileVersion                :
ProductVersion             :
Description                :
Product                    :
Id                         : 1560
PriorityClass              :
HandleCount                : 80
WorkingSet                 : 4194304
PagedMemorySize            : 983040
PrivateMemorySize          : 983040
VirtualMemorySize          : 46186496
TotalProcessorTime         :
BasePriority               : 8
ExitCode                   :
HasExited                  :
ExitTime                   :
Handle                     :
MachineName                : .
MainWindowHandle           : 0
MainWindowTitle            :
MainModule                 :
MaxWorkingSet              :
MinWorkingSet              :
Modules                    :
NonpagedSystemMemorySize   : 7136
NonpagedSystemMemorySize64 : 7136
PagedMemorySize64          : 983040
PagedSystemMemorySize      : 89712
PagedSystemMemorySize64    : 89712
PeakPagedMemorySize        : 1212416
PeakPagedMemorySize64      : 1212416
PeakWorkingSet             : 4300800
PeakWorkingSet64           : 4300800
PeakVirtualMemorySize      : 50155520
PeakVirtualMemorySize64    : 50155520
PriorityBoostEnabled       :
PrivateMemorySize64        : 983040
PrivilegedProcessorTime    :
ProcessName                : armsvc
ProcessorAffinity          :
Responding                 : True
SessionId                  : 0
StartInfo                  : System.Diagnostics.ProcessStartInfo
StartTime                  :
SynchronizingObject        :
Threads                    : {1564, 1572}
UserProcessorTime          :
VirtualMemorySize64        : 46186496
EnableRaisingEvents        : False
StandardInput              :
StandardOutput             :
StandardError              :
WorkingSet64               : 4194304
Site                       :
Container                  :

Notice that you don’t see anything corresponding to any of these fields from the default display – NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)

That’s because they are calculated by PowerShell when the data is formatted to display.  See about_Format.ps1xml for more details

October 15, 2014  1:15 AM

PowerShell Summit Europe 2014 – All videos available

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

All of the recordings from the recent PowerShell Summit in Amsterdam are now available through the PowerShell.org channel on youtube. The playlist for the Summit is https://www.youtube.com/playlist?list=PLfeA8kIs7Coehjg9cB6foPjBojLHYQGb_

Thank you again to the speakers, and attendees, who made for a wonderful first Summit in Europe and more thanks to the people who donated to our appeal to raise funds for the recording equipment.

October 13, 2014  2:22 PM

WMI Associations

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

I saw a question regarding finding the Win32_NetworkAdapter instance using the matching Win32_NetworkAdapterConfiguration starting point. This answers the “which adapter has an IP address of X” type question.

The Index property on a Win32_NetworkAdapterConfiguration instance has the same value as the DeviceId property on the corresponding Win32_NetworkAdapter.

An alternative is to use the ASSOCIATORS WQL keyword.

That approach get s a bit messy but looks like this:

$query = “ASSOCIATORS OF {Win32_NetworkAdapterConfiguration.Index=’18’} WHERE RESULTCLASS = Win32_NetworkAdapter”
Get-WmiObject -Query $query

The CIM cmdlets get a bit better

$config = Get-CimInstance win32_networkadapterconfiguration -Filter “Index = 18”
Get-CimAssociatedInstance -InputObject $config -ResultClassName Win32_NetworkAdapter

Much simpler and you avoid the WQL.

October 13, 2014  11:00 AM

1,000,000 hits

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

This blog and its mirrors have reached the total of 1,000,000 hits for the year to date. Thank you to everyone who takes the time to read my postings

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: