PowerShell for Windows Admins


December 4, 2011  2:06 PM

UK PowerShell Group–November Recording



Posted by: Richard Siddaway
PowerShell v2, User Group, Virtualisation

The November meeting

http://msmvps.com/blogs/richardsiddaway/archive/2011/11/05/powershell-user-group-22-november.aspx

was “What’s new in PowerCLI 5?” presented by Jonathan Medd

The recording of Jonathan’s presentation is available from

https://skydrive.live.com/?cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212929

Jonathan’s slides are available from

http://www.jonathanmedd.net/2011/11/whats-new-in-powercli-5-0-slides-from-uk-powershell-usergroup.html

 

Enjoy

December 4, 2011  5:19 AM

PowerShell v3 CTP 2 install



Posted by: Richard Siddaway
PowerShell 3

Very important – remove CTP1 BEFORE installing CTP 2.  There is no over the top upgrade for the CTP


December 4, 2011  4:59 AM

PowerShell 3 CTP 2



Posted by: Richard Siddaway
PowerShell 3

I’ve been mainly offline the last couple of weeks with health problems – so apologies for not posting as regularly but it was unavoidable.  Back now to discover the awesome news that CTP 2 of PowerShell 3 is available for download from

http://www.microsoft.com/download/en/details.aspx?id=27548

 

it only runs on Win 7 SP1 and Win 2008 R2 SP1.  Both need .NET 4 installed

 

Other useful info from

http://blogs.msdn.com/b/wmi/archive/2011/12/03/windows-management-framework-3-0-community-technology-preview-ctp-2-available-for-download.aspx

 

http://blogs.msdn.com/b/powershell/archive/2011/12/02/windows-management-framework-3-0-community-technology-preview-ctp-2-available-for-download.aspx

 

much more to come on this over the next few weeks


November 21, 2011  1:09 PM

UK PowerShell Group November–reminder



Posted by: Richard Siddaway
PowerShell, User Group, Virtualisation

UK PowerShell Group meeting – Jonathan Medd on “Whats new in PowerCLI 5”

details from http://msmvps.com/blogs/richardsiddaway/archive/2011/11/05/powershell-user-group-22-november.aspx


November 19, 2011  5:46 AM

Using calculated fields in subsequent processing



Posted by: Richard Siddaway
PowerShell

A calculated field can be created in Select-Object or Format-Table. When you use Format-Table processing effectively stops, the pipeline terminates and you are dumping the results to screen. The objects produced by Format-Table are not meant for further processing.

If you use Select-Object to create the calculated field the results are an object on the pipeline that can be used for further processing. As a simple example consider

Get-ChildItem -Path c:\windows

This produces the file sizes in bytes. Lets say that we want the sizes in KB

Get-ChildItem -Path c:\windows |
where {!$_.PSIsContainer} |
select Name, @{Name="Size(KB)"; Expression={[math]::round($($_.Length/ 1kb), 2)}}|
Format-Table -AutoSize

OK this is good. I’ve used the math rounding method as it leaves me with a number rather than a string

No we want to sort of the Size(KB) field so the biggest file is shown first

You might think that

Get-ChildItem -Path c:\windows |
where {!$_.PSIsContainer} |
select Name, @{Name="Size(KB)"; Expression={[math]::round($($_.Length/ 1kb), 2)}}|
sort Size(KB) -Descending |
Format-Table -AutoSize

would work. But we get an error

The term ‘KB’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:4 char:13
+ sort Size(KB <<<< ) -Descending |
+ CategoryInfo : ObjectNotFound: (KB:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

When we have a property name that isn’t a single simple word we need to put it in quotes like this

Get-ChildItem -Path c:\windows |
where {!$_.PSIsContainer} |
select Name, @{Name="Size(KB)"; Expression={[math]::round($($_.Length/ 1kb), 2)}}|
sort -Property "Size(KB)" -Descending |
Format-Table -AutoSize

To work with properties that we create in calculated fields where their names aren’t simple – wrap the name in quotes


November 15, 2011  2:43 PM

Infrastructure Architecture–from the Middle Ages to Now



Posted by: Richard Siddaway
Architecture, Opinion

i often wonder about how we go about performing Infrastructure Architecture in particular and Architecture in general. We spend a lot of time and effort creating frameworks such as Zachman and TOGAF; we create large bodies of data in the form of Enterprise Architecture bodies; we have patterns and reference architecture and the body of white papers and other advertorial content produced by, or on behalf of, vendors.

When it comes down to to actually putting infrastructure on the ground how much of this do we actually use & think about?

Are we like the research scientist looking for  the best answer to solve the problem that we are investigating or are we more like the master mason’s of the Medieval period that built Europe’s great cathedrals, churches and castles?

My feeling is that in many cases we are more like the later.

We have a set of techniques, tricks and tips that we know work because we have used them before. We learn new techniques by working with different people –changing jobs, contractors coming into the organisation  etc.  Often this information ends up being traded. We often serve a long apprenticeship working up through building servers, configuring OS and applications and troubleshooting. When we are deemed worthy – skilled and knowledgeable enough – we are presented with our own projects.

Pretty much parallels the Guild system of the Middle Ages!

Next time you are planning some infrastructure architecture think back on the heritage of how we apply our knowledge. Hopefully one day we will be in the position that it becomes more science than art – when that happens though some of the fun will have gone


November 14, 2011  2:15 PM

Swapping virtual switches



Posted by: Richard Siddaway
Hyper-V, PowerShell v2

Virtualisation is a great technique for creating demo labs. I took my laptop with a bunch of VMs of Windows 8/Server 8 to the PowerShell Deep Dive.  Normally I run my “server” laptop and my development laptop on a switch or connected via a cross over cable. The VM nics are bound to the “server” laptops real ethernet NIC.

This don’t work when you ( a ) forget the cross over cable and ( b ) have the battery collapse on the dev box. I needed to swap the VMs to run off the internal private Hyper-V network.  Swapping the nics between virtual switches is easy but its a pain when you need to do a number of them.

Time for a couple of functions

function set-loopbackswitch {            
            
Get-VM |            
foreach {            
 $nic = Get-VMNIC -VM $_ |             
 where{$_.SwitchName -eq "Local Area Connection - Virtual Network"}             
 Set-VMNICSwitch -NIC $nic -Virtualswitch "LoopBack"            
}            
}            
            
function set-realswitch {            
Get-VM |            
foreach {            
 $nic = Get-VMNIC -VM $_ |             
 where{$_.SwitchName -eq "LoopBack"}             
 Set-VMNICSwitch -NIC $nic -Virtualswitch "Local Area Connection - Virtual Network"            
}            
}

These get the virtual machines and get the nics corresponding to the appropriate switch. It then swaps the the nic to the other switch. Created as 2 functions as its quicker to write.

The functions are based on James O’Neill’s Hyper-V library – if you haven’t got it it is on codeplex


November 13, 2011  1:12 PM

Patch Tuesdays 2012



Posted by: Richard Siddaway
PowerShell, Windows

I’ve shown these functions before but as we head rapidly towards 2012 we need to plan next years schedules.  One perennial for Windows administrators is patching – therefore we need to know patch Tuesdays. This is next years offenders

10 January 2012
14 February 2012
13 March 2012
10 April 2012
08 May 2012
12 June 2012
10 July 2012
14 August 2012
11 September 2012
09 October 2012
13 November 2012
11 December 2012

 

How do we arrive at these dates – simple look at a Calendar or better still use these functions

function get-secondTuesday {            
param([datetime]$date)            
    switch ($date.DayOfWeek){            
        "Sunday"    {$patchTuesday = $date.AddDays(9); break}             
        "Monday"    {$patchTuesday = $date.AddDays(8); break}             
        "Tuesday"   {$patchTuesday = $date.AddDays(7); break}             
        "Wednesday" {$patchTuesday = $date.AddDays(13); break}             
        "Thursday"  {$patchTuesday = $date.AddDays(12); break}             
        "Friday"    {$patchTuesday = $date.AddDays(11); break}             
        "Saturday"  {$patchTuesday = $date.AddDays(10); break}             
     }            
     $patchTuesday.ToLongDateString()            
}            
            
function Get-PatchTuesday {            
param (            
    [parameter(ValueFromPipeline=$true)]            
    [int]$year = (Get-Date).Year,            
                
    [switch]$nextmonth            
    )            
                 
    if ($nextmonth){            
        $now = Get-Date            
        $d = Get-Date -Day 1 -Month $($now.Month + 1) -Year $now.Year            
        get-secondTuesday $d            
    }            
    else {            
        1..12 | foreach {            
            $d = [datetime]"$_/1/$year"            
            get-secondTuesday $d            
        }                
    }            
}

We run the function like this

Get-PatchTuesday -year 2012

It takes the year and for each month in the year creates a datetime object for the first of the month.  That date is fed to the get-secondtuesday function which looks at the day of the week and calculates the second Tuesday.

If your patching Window is a specific day in the month then modify the functions to calculate those dates and feed them straight to your change control process


November 11, 2011  2:48 PM

Set registry key owner



Posted by: Richard Siddaway
PowerShell v2, Registry

In chapter 7 of PowerShell and WMI I stated that I would post a .NET version of a script to set ownership of a registry key. The WMI method needs Vista or above so we need the .NET version for pre-Vista operating systems.

function set-regkeyowner {            
[CmdletBinding()]            
param (            
 [parameter(Mandatory=$true)]            
 [string]            
 [Validateset(“HKCR”, “HKCU”, “HKLM”, "HKUS", "HKCC")]            
  $hive,            
            
 [parameter(Mandatory=$true)]            
 [string]$key            
)              
PROCESS {             
Write-Verbose "Set Hive"            
switch ($hive){            
 “HKCR” {$reg = [Microsoft.Win32.Registry]::ClassesRoot}            
 “HKCU” {$reg = [Microsoft.Win32.Registry]::CurrentUser}            
 “HKLM” {$reg = [Microsoft.Win32.Registry]::LocalMachine}            
 "HKUS" {$reg = [Microsoft.Win32.Registry]::Users}            
 "HKCC" {$reg = [Microsoft.Win32.Registry]::CurrentConfig}            
}            
            
$permchk = [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree            
$regrights = [System.Security.AccessControl.RegistryRights]::ChangePermissions            
            
Write-Verbose "Open Key and get access control"            
$regkey = $reg.OpenSubKey($key, $permchk, $regrights)            
$rs = $regkey.GetAccessControl()            
            
Write-Verbose "Create security principal"            
$user = New-Object -TypeName Security.Principal.NTaccount -ArgumentList "Administrators"            
            
$rs.SetGroup($user)             
$rs.SetOwner($user)             
$regkey.SetAccessControl($rs)            
}            
}

Take a hive and key as parameters. Use a switch to set the Registry enumeration and then set the permissions and rights we want. Open the key and get the access controls.

Create a security principal for the Administrators group and set the group and owner in the access control. Use SetAccessControl to change the permissions


November 8, 2011  1:20 PM

Hosts file – add an IPv6 address



Posted by: Richard Siddaway
Network, PowerShell v2

This builds on adding an IPv4 address – http://msmvps.com/blogs/richardsiddaway/archive/2011/10/24/hosts-file-add-a-record.aspx

function add-IPv6hostfilecontent {            
 [CmdletBinding()]            
 param (            
  [parameter(Mandatory=$true)]            
  [string]$IPAddress,            
              
  [parameter(Mandatory=$true)]            
  [string]$computer            
 )            
 $file = Join-Path -Path $($env:windir) -ChildPath "system32\drivers\etc\hosts"            
 if (-not (Test-Path -Path $file)){            
   Throw "Hosts file not found"            
 }            
 $data = Get-Content -Path $file             
 $data += "$IPAddress  $computer"            
 Set-Content -Value $data -Path $file -Force -Encoding ASCII             
}

 

The only difference is that I’ve removed the regex that checks an IPv4 address.  i haven’t been able to figure out a sensible regex for an IPv6 address. if any one wants to post one as a comment I’ll add it to the function with fill credit

The get-hostfilecontent from http://msmvps.com/blogs/richardsiddaway/archive/2011/10/23/reading-the-hosts-file.aspx works with IPv4 and IPv6 addresses

PS> get-hostfilecontent

Server                                       IPAddress                                  
——                                       ———                                  
RSLAPTOP01                                   fe80:0000:0000:0000:4547:ee51:7aac:521e    
RSLAPTOP01                                   10.10.54.202


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: