PowerShell for Windows Admins


August 28, 2014  12:56 PM

Patching Server Core

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell, Windows Server Core

I’ve been rebuilding my test lab after installing a SSD into the machine running it in place of the SATA drive.  Huge improvement in load speed of virtual machines – well worth the cost.

I usually have a number of server core machines in the lab and use WSUS for patching.  One issue I’d never really resolved was patching those server core machines  – the control panel fro Windows Update isn’t available!

Finally found a solution in the Windows Update PowerShell module from

http://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc

Install the module and then you can install your patches using

Get-WUInstall –AcceptAll

I’m running Windows 2012 R2 on all my servers so the modules auto load

August 28, 2014  11:26 AM

European Summit deadline approaching

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell

There are just over two weeks left for you to register for the European PowerShell Summit. At the moment we are still short of the number that would enable us to repeat a European Summit in 2015.  We had a lot of comments from people stating they wanted a Summit in Europe.  Now is the time to step up and support that idea.

Hope to see you there


August 28, 2014  6:15 AM

DSC Resource Kit–wave 6

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell

The next wave of the DSC resource kit is available with some new resources and updates to old favourites.

Details from:

http://blogs.msdn.com/b/powershell/archive/2014/08/20/dsc-resource-kit-wave-6-is-here.aspx


August 21, 2014  2:04 AM

Learning, always learning

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Books, PowerShell

PowerShell is going mainstream amongst the administrator community – it may seem slow but the last couple of years has definitely seen a sustained upswing in adoption in my experience. As more people are demonstrating the benefits we see more people asking how they can learn PowerShell.

 

Two good ways come to mind. First is go on a course delivered by a recognised expert – if you’re thinking of attending a PowerShell course find out who is delivering it and look them up. If they don’t seem like an expert look for another course. There is s lot of bad practice being communicated and you rally want to cut through that and learn from a master of the subject.

 

if you don’t like, or can’t attend, a course then your best bet is Don Jones’ book – Learn PowerShell in a Month of Lunches – http://www.manning.com/jones3/

 

That completes the first part of your action. The second part is learning how to use PowerShell to administer the technology, or technologies, you work with.  Assuming you understand how to administer the underlying technology you need something to help you learn how to apply PowerShell to that technology. These are books I’d recommend:

For Active Directory

Learn Active Directory in a Month of Lunches – http://www.manning.com/siddaway3/

 

For IIS

Learn IIS in a Month of Lunches  – http://www.manning.com/helmick/

 

For more general administration

PowerShell in Practice – http://www.manning.com/siddaway/

PowerShell and WMI – http://www.manning.com/siddaway2/

 

For VMware

VMware vSphere PowerCLI Reference: Automating vSphere Administration

Managing VMware Infrastructure with Windows PowerShell

 

These are books that I’ve used or worked on in one form or another and that I’m prepared to recommend. There are books on other administration through PowerShell topics but not having read them I can’t recommend for or against

 

I’ll update this post periodically as I work through more technologies.


August 20, 2014  10:19 AM

Count property

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell

Its frequently said that PowerShell is so big that no one can know everything about it.  I proved that today when I “discovered” a change in PowerShell of which I wasn’t aware.

 

If you create an array:

£> $a = 1,2,3

You can then get the number of members of that array i.e. its length

 

£> $a.count
3

 

£> $a[0]
1

 

In PowerShell 1.0 and 2.0 if you tried that on a variable that only held a single value you would get an error when you tried to access the first value:

£> $b = 1
£> $b.count

The count property returns nothing

 

£> $b[0]
Unable to index into an object of type System.Int32.
At line:1 char:4
+ $b[ <<<< 0]
+ CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : CannotIndex

 

This changed in PowerShell 3.0 and later

£> $b = 1
£> $b.count
1
£> $b[0]
1

 

You can even try other indices
£> $b[1]
£>

 

And just get nothing back rather than an error.

 

This is really useful as you can now safely test on the Count property and if the value is greater than 1 to determine if its a collection.  Alternatively always treat it as a collection and iterate over the number of elements.  I can see this simplifying things for me in quite a few situations


August 20, 2014  7:49 AM

Split-Path serendipity

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell

I’ve used Split-Path and its associated cmdlet Join-Path a lot when working with file system paths. Something I read today started me asking if it would work with URLs

 

It does:

 

£> Split-Path -Path ‘http://powershell.org/wp/forums/forum/windows-powershell-qa/’ -Leaf
windows-powershell-qa
£> Split-Path -Path ‘http://powershell.org/wp/forums/forum/windows-powershell-qa/’ -Parent
http:\\powershell.org\wp\forums\forum

 

£> Split-Path -Path ‘http://powershell.org/wp/forums/forum/windows-powershell-qa/’ -NoQualifier
//powershell.org/wp/forums/forum/windows-powershell-qa/
£> Split-Path -Path ‘http://powershell.org/wp/forums/forum/windows-powershell-qa/’ -Qualifier
http:

 

The –Resolve parameter won’t work because its not a file system path but if you need to play with URLs then could be useful.

 

Just for completeness Join-Path won’t work with URLs because its attempting to resolve the file path


August 18, 2014  12:57 PM

European Summit countdown #1

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell

There are four weeks left to register for the Summit if you are going to attend. Our numbers are moving in the right direction but we still need more registrations to make a 2015 Summit feasible.


August 18, 2014  12:53 PM

DNS client settings

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
DNS, PowerShell

Following yesterdays post there are a couple of other cmdlets worth looking at if you want to dig into the DNS settings on your client machines.

Get-DnsClient wil show you the DNS relsted settings for all of your network interfaces by default.  To investigate a single interface

 

£> Get-DnsClient -InterfaceAlias vEthernet* | fl
InterfaceAlias                     : vEthernet (External01)
InterfaceIndex                     : 20
ConnectionSpecificSuffix           :
ConnectionSpecificSuffixSearchList : {}
RegisterThisConnectionsAddress     : True
UseSuffixWhenRegistering           : False

InterfaceAlias                     : vEthernet (Internal01)
InterfaceIndex                     : 16
ConnectionSpecificSuffix           :
ConnectionSpecificSuffixSearchList : {}
RegisterThisConnectionsAddress     : True
UseSuffixWhenRegistering           : False

 

You can also see the DNS servers a particular interface will use:

£> Get-DnsClientServerAddress -InterfaceAlias vEthernet*

InterfaceAlias               Interface Address ServerAddresses
Index     Family
————–               ——— ——- —————
vEthernet (External01)              20 IPv4    {192.168.0.1}
vEthernet (External01)              20 IPv6    {}
vEthernet (Internal01)              16 IPv4    {}
vEthernet (Internal01)              16 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}


August 17, 2014  1:02 PM

Have you been talking to strangers?

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
DNS, PowerShell

Want to know the machines to which your machine has been connecting?

 

Try looking in the client DNS cache:

 

Get-DnsClientCache

 

will show a wealth of useful data.  All in the form:

£> Get-DnsClientCache | where Entry -like ‘*www.intelliweather.net*’ | fl *
TTL                   : 39
Caption               :
Description           :
ElementName           :
InstanceID            :
Data                  : cache1.intelliweather.net
DataLength            : 8
Entry                 : www.intelliweather.net
Name                  : www.intelliweather.net
Section               : 1
Status                : 0
TimeToLive            : 39
Type                  : 5
PSComputerName        :
CimClass              : ROOT/StandardCimv2:MSFT_DNSClientCache
CimInstanceProperties : {Caption, Description, ElementName, InstanceID…}
CimSystemProperties   : Microsoft.Management.Infrastructure.CimSystemProperties

TTL                   : 39
Caption               :
Description           :
ElementName           :
InstanceID            :
Data                  : 38.114.169.29
DataLength            : 4
Entry                 : www.intelliweather.net
Name                  : cache1.intelliweather.net
Section               : 1
Status                : 0
TimeToLive            : 39
Type                  : 1
PSComputerName        :
CimClass              : ROOT/StandardCimv2:MSFT_DNSClientCache
CimInstanceProperties : {Caption, Description, ElementName, InstanceID…}
CimSystemProperties   : Microsoft.Management.Infrastructure.CimSystemProperties

 

 

What is interesting is the Time To Live settings on some of the records:

£> Get-DnsClientCache | sort TTL -Descending | group TTL -NoElement

Count Name
—– —-
7 74538
1 70203
1 64639
1 53300
1 53299
1 16441
2 9308
1 2579
1 2573
3 2475
6 2469
2 2327
2 1986
1 1890
1 1089
1 999
2 899
2 891
2 878
3 728
1 724
6 711
1 631
1 458
1 412
1 363
1 133
15 0

 

Some of those records will be around for a long time!


August 14, 2014  2:01 PM

foreach

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
PowerShell

I was asked about foreach today and responded with a description of who foreach-object works. Thinking about it I should have realised that part of the issue with foreach is the confusion that arises between foreach and foreach – -  that is the difference between the foreach PowerShell statement and the foreach alias of the foreach-object cmdlet.

 

To unravel the confusion there are two different things referred to as foreach. The confusion is that they do very similar things but are used in different ways.

 

The first is the PowerShell statement which is used to step through each value in a collection of values:

 

$procs = Get-Process

foreach ($proc in $procs) {

New-Object -TypeName PSObject -Property @{
Name = $proc.Name
SysMen =  $proc.NonpagedSystemMemorySize + $proc.PagedSystemMemorySize64
}

}

 

You create your collection of objects and then use foreach to step through them. It is convention to make the collection plural and the individual member of the collection its singular.  Within the script block you can define what happens to the object.

 

I know I could have a performed this action is a simpler way but I wanted to demonstrate how foreach works. The simpler way would be:

Get-Process |
select Name,
@{Name = ‘SysMen’;
Expression = {$_.NonpagedSystemMemorySize + $_.PagedSystemMemorySize64}}

 

Now we’ve got that out of the way what about the other foreach which is the alias of foreach-object.  This can be use to iterate over a collection of objects. The main difference is that the objects are usually piped into foreach:

 

Get-Process |
foreach {

New-Object -TypeName PSObject -Property @{
Name = $_.Name
SysMen =  $_.NonpagedSystemMemorySize + $_.PagedSystemMemorySize64
}

}

 

If you don’t like using $_ to represent the object on the pipeline try

Get-Process |
foreach {

New-Object -TypeName PSObject -Property @{
Name = $psitem.Name
SysMen =  $psitem.NonpagedSystemMemorySize + $psitem.PagedSystemMemorySize64
}

}

 

which is exactly equivalent to

Get-Process |
ForEach-Object {

New-Object -TypeName PSObject -Property @{
Name = $psitem.Name
SysMen =  $psitem.NonpagedSystemMemorySize + $psitem.PagedSystemMemorySize64
}

}

 

Using the cmdlet or its alias you can set up script blocks to process once when the first object reaches foreach (BEGIN), once per object on the pipeline (PROCESS) and once when the last object has been processed (END)

Get-Process |
ForEach-Object `
-BEGIN {
Write-Host “First object about to be processed”
} `
-PROCESS {
New-Object -TypeName PSObject -Property @{
Name = $psitem.Name
SysMen =  $psitem.NonpagedSystemMemorySize + $psitem.PagedSystemMemorySize64
}
}`
-END {
Write-Host “Last object processed”
}

 

Your ouput looks like this

 

First object about to be processed

Name                                                                      SysMen
—-                                                                      ——
armsvc                                                                    164096
concentr                                                                  200400
conhost                                                                   119104
csrss                                                                     153664
csrss                                                                     407760
<truncated>

WUDFHost                                                                  103696
WWAHost                                                                   778816
WWAHost                                                                   785120
Yammer.Notifier                                                           566304
Last object processed

 

More info is available in the help files for foreach-object and about_foreach


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: