PowerShell for Windows Admins


May 18, 2018  11:39 AM

Format Data

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

PowerShell will format the output of objects that it knows about. For instance Get-Process shows different sets of properties depending on whether you choose a table or list view. The format data is stored in files named *.format.ps1xml.

In Windows PowerShell the format files are found in C:\Windows\System32\WindowsPowerShell\v1.0. In PowerShell v6 the format files are stored with the appropriate module.

If you want to create formatting for a new object, or change the formatting for an existing object the best place to start is to export the format data for an existing object

Get-FormatData -TypeName System.Diagnostics.Process | Export-FormatData -Path f5.txt

gets the format data for the object used in Get-Process.

The drawback is that is presented a long string

<?xml version=”1.0″ encoding=”utf-8″?><Configuration><ViewDefinitions><View><Name>process</Name><ViewSelectedBy><TypeNam
e>System.Diagnostics.Process</TypeName></ViewSelectedBy><TableControl><TableHeaders><TableColumnHeader><Label>Handles</L
abel><Width>7</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Label>NPM(K)</Label><Width>7</W
idth><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Label>PM(K)</Label><Width>8</Width><Alignment>R
ight</Alignment></TableColumnHeader><TableColumnHeader><Label>WS(K)</Label><Width>10</Width><Alignment>Right</Alignment>
</TableColumnHeader><TableColumnHeader><Label>CPU(s)</Label><Width>10</Width><Alignment>Right</Alignment></TableColumnHe
ader><TableColumnHeader><Width>6</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Width>3</Wid
th><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader /></TableHeaders><TableRowEntries><TableRowEntry><
TableColumnItems><TableColumnItem><PropertyName>HandleCount</PropertyName></TableColumnItem><TableColumnItem><ScriptBloc
k>;</ScriptBlock></TableColumnItem><TableColumnItem><ScriptBlock>;</ScriptBlock></TableColumnItem><TableColumnItem><Scri
ptBlock>;</ScriptBlock></TableColumnItem><TableColumnItem><ScriptBlock>;</ScriptBlock></TableColumnItem><TableColumnItem
><PropertyName>Id</PropertyName></TableColumnItem><TableColumnItem><PropertyName>SI</PropertyName></TableColumnItem><Tab
leColumnItem><PropertyName>ProcessName</PropertyName></TableColumnItem></TableColumnItems></TableRowEntry></TableRowEntr
ies></TableControl></View><View><Name>process</Name><ViewSelectedBy><TypeName>System.Diagnostics.Process</TypeName></Vie
wSelectedBy><WideControl><WideEntries><WideEntry><WideItem><PropertyName>ProcessName</PropertyName></WideItem></WideEntr
y></WideEntries></WideControl></View></ViewDefinitions></Configuration>

And you have to manage the pretty printing yourself.

In PowerShell v6.1 the output is automatically pretty printed

Get-FormatData -TypeName System.Diagnostics.Process | Export-FormatData -Path f6.txt

<?xml version=”1.0″ encoding=”utf-8″?>
<Configuration>
<ViewDefinitions>
<View>
<Name>process</Name>
<ViewSelectedBy>
<TypeName>System.Diagnostics.Process</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>NPM(K)</Label>
<Width>7</Width>
<Alignment>Right</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>PM(M)</Label>
<Width>8</Width>
<Alignment>Right</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>WS(M)</Label>
<Width>10</Width>
<Alignment>Right</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>CPU(s)</Label>
<Width>10</Width>
<Alignment>Right</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Width>7</Width>
<Alignment>Right</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Width>3</Width>
<Alignment>Right</Alignment>
</TableColumnHeader>
<TableColumnHeader />
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>;</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>;</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>;</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>;</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Id</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>SI</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ProcessName</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>process</Name>
<ViewSelectedBy>
<TypeName>System.Diagnostics.Process</TypeName>
</ViewSelectedBy>
<WideControl>
<WideEntries>
<WideEntry>
<WideItem>
<PropertyName>ProcessName</PropertyName>
</WideItem>
</WideEntry>
</WideEntries>
</WideControl>
</View>
</ViewDefinitions>
</Configuration>

which makes it much easier to work with

May 15, 2018  8:11 AM

where –not

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

PowerShell v6.1 preview 2 has added the where –not option.

The option adds another parameter to the syntax

where-object <property name> <operator like parameter> <value>

Couple of examples of using the syntax

Get-Process | where CPU -gt 12

Get-Service | where Status -like ‘Stop*’

Use –Not when you’re looking for properties that aren’t set. For example

Get-Service | where -Not DependentServices

or

Get-Process | where -Not StartTime


May 11, 2018  8:52 AM

Calculating standard deviation

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Calculating a standard deviation isn’t a difficult exercise but PowerShell v6.1 offers an easier method.

In Windows PowerShell v5.1 and PowerShell v6.0 the Measure-Object cmdlet has this syntax

PS> Get-Command Measure-Object -Syntax

Measure-Object [[-Property] <string[]>] [-InputObject <psobject>] [-Sum] [-Average] [-Maximum] [-Minimum] [<CommonParameters>]

Measure-Object [[-Property] <string[]>] [-InputObject <psobject>] [-Line] [-Word] [-Character] [-IgnoreWhiteSpace] [<CommonParameters>]

In PowerShell v6.1.0-preview.2 this changes to

PS> Get-Command Measure-Object -Syntax

Measure-Object [[-Property] <string[]>] [-InputObject <psobject>] [-StandardDeviation] [-Sum] [-Average] [-Maximum] [-Minimum] [<CommonParameters>]

Measure-Object [[-Property] <string[]>] [-InputObject <psobject>] [-Line] [-Word] [-Character] [-IgnoreWhiteSpace] [<CommonParameters>]

You’ve now got a standard deviation option.

How do you use it?

PS> 1..517 | Measure-Object -Sum -Average -StandardDeviation

Count : 517
Average : 259
Sum : 133903
Maximum :
Minimum :
StandardDeviation : 149.389312424506
Property :

There’s probably a few other calculations that would be useful to add to Measure-Object


May 9, 2018  7:58 AM

PowerShell problem reporting

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

There seems to be a lot of confusion about PowerShell problem reporting.

The difference between Windows PowerShell (the one you find pre-installed on Windows machines) current version v5.1 and PowerShell (the open source project) current version v6.0 isn’t really understood and that lies at the heart of the problem.

If you have a problem with Windows PowerShell and you think its a bug the place to report it is here – https://windowsserver.uservoice.com/forums/301869-powershell

If you have a problem with PowerShell and you want to report a bug or request a change or new feature the place to do it is here – https://github.com/PowerShell/PowerShell/issues

The two flavours of PowerShell should be regarded as completely different technologies and treated accordingly.


May 3, 2018  5:30 AM

PowerShell Summit 2018 videos

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The PowerShell Summit 2018 videos are available at

https://www.youtube.com/watch?v=sN7xw_jq_64&list=PLfeA8kIs7CocGXuezOoYtLRdnK9S_Mq3e

Enjoy


April 30, 2018  1:53 PM

PowerShell v6.1 Range Operator

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The PowerShell v6.1 Rang Operator has been enhanced to deal with letters as well as numbers.

The range operator has always been available in PowerShell. It can be used to generate a range of integers for example:

PS>  (1..10) -join ‘,’
1,2,3,4,5,6,7,8,9,10
PS>  (10..1) -join ‘,’
10,9,8,7,6,5,4,3,2,1
PS>  (-10..10) -join ‘,’
-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10
PS>  (10..-10) -join ‘,’
10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10

In PowerShell v6.1 the range operator can also produce sequences of letters

PS>  ‘a’..’z’ -join ‘,’
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
PS>  ‘z’..’a’ -join ‘,’
z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a

PS>  ‘A’..’Z’ -join ‘,’
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
PS>  ‘Z’..’A’ -join ‘,’
Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A

Be careful with mixing case

PS>  ‘Z’..’a’ -join ‘,’
Z,[,\,],^,_,`,a
PS>  ‘a’..’Z’ -join ‘,’
a,`,_,^,],\,[,Z
PS>  ‘z’..’A’ -join ‘,’
z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,`,_,^,],\,[,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A
PS>  ‘A’..’z’ -join ‘,’
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,\,],^,_,`,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z

As you might get more than you wanted  🙂


April 30, 2018  7:29 AM

-Contains or -In

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

PowerShell has two operators that do very similar jobs –contains and –in. So which should you use –contains or –in.

From the help file.

-Contains: Tells whether a collection of reference values includes a single test value.

-In: Tells whether a test value appears in a collection of reference values

OK – they’re subtly different.

The real difference comes in how you use them

-Contains has been available since PowerShell v1. Its used like this

<reference values> –contains <value>

for example

PS> $rb = ‘Red’, ‘Orange’, ‘Yellow’, ‘Green’, ‘Blue’, ‘Indigo’, ‘Violet’
PS> $rb -contains ‘yellow’
True
PS> $rb -contains ‘black’
False

True or false is returned depending if the value is part of the collection or not

By contrast –In (introduced in PowerShell v3) uses this syntax

<value> –in <reference values>

for example

PS> $rb = ‘Red’, ‘Orange’, ‘Yellow’, ‘Green’, ‘Blue’, ‘Indigo’, ‘Violet’
PS> ‘Blue’ -in $rb
True
PS> ‘Black’ -in $rb
False

The difference between the two is the order of the operands.

-In was introduced for use with the short hand syntax of Where-Object

where <property value> operator <value>

so try this

$rb = ‘Red’, ‘Orange’, ‘Yellow’, ‘Green’, ‘Blue’, ‘Indigo’, ‘Violet’
$colours = ‘Black’, ‘White’, ‘Red’

$co = foreach ($colour in $colours) {
New-Object -TypeName psobject -Property @{
Colour = $colour
}
}

Then run

$co | where Colour -in $rb

$co | where Colour -contains $rb

$co | where $rb -contains colour

$co | where {$rb -contains $_.colour}

You’ll see the correct answer from the first and fourth options and nothing from the second because the values are the wrong way round. The third option errors

Where-Object : A positional parameter cannot be found that accepts argument
‘System.Object[]’.
At line:1 char:7
+ $co | where $rb -contains colour
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBi
ndingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell
.Commands.WhereObjectCommand


April 28, 2018  1:38 PM

Installing PowerShell v6.1 preview 2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The MSI for installing PowerShell v6.1 preview 2 has a screen for optional actions:

Add PowerShell to Path environment variable
Register Windows Event Logging Manifest
Enable PowerShell remoting
Add ‘open here’ context menus to Explorer

The 6.1 preview installs side by side with PowerShell v6.0.x

Test-Connection in v6.1

PS> Get-Command Test-Connection -Syntax

Test-Connection [-TargetName] <string[]> [-Ping] [-IPv4] [-IPv6] [-ResolveDestination] [-Source <string>] [-MaxHops <int>] [-Count <int>] [-Delay <int>] [
-BufferSize <int>] [-DontFragment] [-TimeoutSeconds <int>] [-Quiet] [<CommonParameters>]

Test-Connection [-TargetName] <string[]> [-Ping] [-IPv4] [-IPv6] [-ResolveDestination] [-Source <string>] [-MaxHops <int>] [-Delay <int>] [-BufferSize <int>] [-DontFragment] [-Continues] [-TimeoutSeconds <int>] [-Quiet] [<CommonParameters>]

Test-Connection [-TargetName] <string[]> -MTUSizeDetect [-IPv4] [-IPv6] [-ResolveDestination] [-TimeoutSeconds <int>] [-Quiet] [<CommonParameters>]

Test-Connection [-TargetName] <string[]> -Traceroute [-IPv4] [-IPv6] [-ResolveDestination] [-Source <string>] [-MaxHops <int>] [-TimeoutSeconds <int>] [-Quiet] [<CommonParameters>]

Test-Connection [-TargetName] <string[]> -TCPPort <int> [-IPv4] [-IPv6] [-ResolveDestination] [-Source <string>] [-TimeoutSeconds <int>] [-Quiet] [<Common
Parameters>]

is very different to Test-Connection in v5.1

Test-Connection [-ComputerName] <string[]> [-AsJob] [-DcomAuthentication <AuthenticationLevel>] [-WsmanAuthentication <s
tring>] [-Protocol <string>] [-BufferSize <int>] [-Count <int>] [-Impersonation <ImpersonationLevel>] [-ThrottleLimit <i
nt>] [-TimeToLive <int>] [-Delay <int>] [<CommonParameters>]

Test-Connection [-ComputerName] <string[]> [-Source] <string[]> [-AsJob] [-DcomAuthentication <AuthenticationLevel>] [-W
smanAuthentication <string>] [-Protocol <string>] [-BufferSize <int>] [-Count <int>] [-Credential <pscredential>] [-Impe
rsonation <ImpersonationLevel>] [-ThrottleLimit <int>] [-TimeToLive <int>] [-Delay <int>] [<CommonParameters>]

Test-Connection [-ComputerName] <string[]> [-DcomAuthentication <AuthenticationLevel>] [-WsmanAuthentication <string>] [
-Protocol <string>] [-BufferSize <int>] [-Count <int>] [-Impersonation <ImpersonationLevel>] [-TimeToLive <int>] [-Delay
<int>] [-Quiet] [<CommonParameters>]

You’ll need to experiment to see the differences and to determine which works best for you.

Test –json I’m not sure if its working correctly or not – it throws an exception with a JSON file I’ve used many times and also with this

PS> Get-Process p* | ConvertTo-Json | Test-Json
Test-Json : Cannot parse the JSON.
At line:1 char:35
+ Get-Process p* | ConvertTo-Json | Test-Json
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: ([
{
“Sa…rocess”
}
]:String) [Test-Json], Exception
+ FullyQualifiedErrorId : InvalidJson,Microsoft.PowerShell.Commands.TestJsonCommand

needs some investigation.


April 28, 2018  8:16 AM

Access module and functions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

A long time ago I wrote a module for working with Access databases. I also added a couple of independent functions. The  Access module and functions are now available on github.

People have asked about getting the module and while its had a number of temporary homes its permanent home is now the github repsoitory – https://github.com/RichardSiddaway/AccessFunctions

The module comprises the following functions:

Add-AccessRecord
Close-AccessDatabase
Get-AccessData
Get-AccessStoredProcedure
Get-AccessTableDefinition
Invoke-AccessStoredProcedure
New-AccessColumn
New-AccessDatabase
New-AccessIndex
New-AccessStoredProcedure
New-AccessTable
Open-AccessDatabase
Remove-AccessColumn
Remove-AccessData
Remove-AccessIndex
Remove-AccessStoredProcedure
Remove-AccessTable
Reset-Autonum
Set-AccessData
Test-AccessConnection

The independent functions are:

bulkload.ps1
new-table.ps1

All of the functions are supplied as is without warranty or guarantee.


April 28, 2018  4:06 AM

PowerShell v6.1 preview 2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

PowerShell v6.1 preview 2 is now available for download from https://github.com/PowerShell/PowerShell/releases

The breaking changes shouldn’t affect your code as they’re for telemetry and installation

Test-Connection is now available in v6

Export-FormatData will pretty print the XML rather than just giving you a single string

There’s now a Test-Json cmdlet and a –Not parameter has been added to Where-Object

OpenSSH has moved to https://github.com/PowerShell/openssh-portable but releases are managed through https://github.com/PowerShell/Win32-OpenSSH/releases

Confused? So am I.

This may be linked to the fact that OpenSSH is appearing as an optional install in Windows 10 and Windows Server (post v1709) though the server only had the option for the client last time I looked.

The OpenSSH story is becoming more confusing every time I look at it. It needs to be sorted if remoting between Linux and Windows is to become a thing.


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: