PowerShell for Windows Admins


January 28, 2013  12:16 PM

PowerShell and Active Directory–reminder

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Quick reminder for tomorrow’s session from the UK PowerShell group.  Details from:

http://msmvps.com/blogs/richardsiddaway/archive/2013/01/16/uk-powershell-group-29-january-2013.aspx

January 19, 2013  11:05 AM

Piping between functions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question came up about piping between advanced functions. The input to the second function might be an array. To illustrate how this works imagine a function that gets disk information – or better still use this one.

function get-mydisk{             
[CmdletBinding()]             
param (             
   [string]$computername="$env:COMPUTERNAME"             
)             
BEGIN{}#begin             
PROCESS{            
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername |            
foreach {            
New-Object -TypeName PSObject -Property @{            
 Disk = $_.DeviceID            
 Free = $_.FreeSpace            
 Size = $_.Size            
}            
}            
}#process             
END{}#end            
}

Use a computername as a parameter. Use WMI to get the disk information and output an object.

PS> get-mydisk | ft -AutoSize

Disk         Free         Size

—-         —-         —-

C:   149778239488 249951154176

D:       69271552    104853504

E:                           
F:                           

This works as well

 

PS> get-mydisk | where Size -gt 0 | ft -AutoSize

Disk         Free         Size

—-         —-         —-

C:   149778108416 249951154176

D:       69271552    104853504

You now have a function outputs objects that behave properly on the pipeline.

So now you want those objects piped into another function or you want an array of objects used as the input

function get-freeperc {             
[CmdletBinding()]             
param (             
[parameter(ValueFromPipeline=$true)]            
  [Object[]]$disklist             
)             
BEGIN{}#begin             
PROCESS{            
            
foreach ($disk in $disklist){            
 if ($disk.Size -gt 0){            
   $disk | Select Disk,            
   @{N="Size(GB)"; E={[math]::Round( ($($_.Size)/1GB), 2 )}},            
   @{N="FreePerc"; E={[math]::Round( ($($_.Free) / $($_.Size))*100, 2 )}}            
 }            
}            
            
}#process             
END{}#end            
}
  • Set the parameter to accept pipeline input
  • Set the parameter to accept an array of objects
  • Use a process block
  • Use a foreach block in the process block

This works

PS> get-mydisk | get-freeperc | ft -AutoSize

Disk Size(GB) FreePerc

—- ——– ——–

C:     232.79    59.92

D:        0.1    66.07

or this

$disks = get-mydisk 
get-freeperc -disklist $disks 

or this

get-freeperc -disklist (get-mydisk)


January 17, 2013  1:49 PM

Starting virtual machines for WSUS

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

My test environment usually has a dozen or so machines at any one time. Some of these are short lived and used for a particular piece of testing – others are kept for  years. I decided that I wanted to keep up to date on the patching of these virtual machines so installed WSUS on a Windows 2012 box.

One issue is that if a VM isn’t started for 10 days WSUS starts complaining that it hasn’t been contacted and if you run the WSUS clean up wizard the non-reporting servers may be removed. Checking the WSUS console for which machines haven’t sync’d recently is a chore.

In Windows 2012 both WSUS and Hyper-V come with a PowerShell module. This means I can do this:

$date = (Get-Date).AddDays(-10)            
Get-WsusComputer -ToLastSyncTime $date |            
sort  LastSyncTime |            
select -First 4 |            
foreach {             
 $computer = ($_.FullDomainName -split "\.")[0]            
 Start-VM -Name $computer -ComputerName Server02 -Passthru            
}

I’m using the WSUS server as my admin box but if you were accessing a remote WSUS machine change the code to

Get-WsusServer -Name w12sus -PortNumber 8530 | Get-WsusComputer –ToLastSyncTime $date |

I sorted the computers WSUS knows about by date – picked the last 4 to sync so I didn’t overwhelm the Hyper-V host and started them up. Only trick is to get the computer name out of the FullDomainName property.


January 17, 2013  2:26 AM

Account SIDs–hopefully my last word

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Ok the embarrassing moral of this story is that you shouldn’t answer questions in a hurry at the end of the evening. 5 minutes after shutting down I realised that there is a far, far simpler way to get the info. Win32_AccountSID is a WMI linking class. It links Win32_SystemAccount and Win32_SID classes.

Get-WmiObject -Class Win32_SystemAccount | select Caption, Domain, Name, SID, LocalAccount

gets you all you need


January 16, 2013  4:47 PM

Account SIDs revisited

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I realised there is an easier way to get the data

function get-SID {            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
Get-WmiObject -Class Win32_AccountSID -ComputerName $computername |            
foreach {            
             
 $exp = "[wmi]'" + $($_.Element) + "'"            
 Invoke-Expression -Command $exp |            
 select Domain, Name, SID, LocalAccount            
}            
}

Use the wmi type accelerator with the path from the Element and you can just select the data you want.  As a bonus you can discover if the account is local or not


January 16, 2013  4:33 PM

Passing function names

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question asked about passing a function name into another function which then called the function. It sounds worse than it is. if you need to pass the name of a command and then call it try using invoke-expression

function ffour {            
Get-Random            
}            
            
            
function fthree {            
Get-Date            
}            
            
            
function ftwo {            
param(            
 [string]$fname            
)            
            
Invoke-Expression $fname            
}            
            
            
"date"            
ftwo fthree            
            
"random"            
ftwo ffour


January 16, 2013  4:21 PM

Account SIDs

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question on the forum asked about finding the accounts and SIDs on the local machine.

function get-SID {            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
Get-WmiObject -Class Win32_AccountSID -ComputerName $computername |            
foreach {            
 $da =  (($_.Element).Split(".")[1]).Split(",")            
 $sid = ($_.Setting -split "=")[1] -replace '"',''            
            
 $props = [ordered]@{            
 Domain = ($da[0] -split "=")[1] -replace '"',''            
 Account = ($da[1] -split "=")[1] -replace '"',''            
 SID = $sid            
 }            
             
 New-Object -TypeName PSObject -Property $props            
}            
            
}

Pass a computer name into the function – default is local machine.

Use the AccountSID class which links Win32_SystemAccount and Win32_SID.  For each returned instance clean up the data and create an object with three properties – domain, account and SID.

You will see more than you thought – some very useful information buried in there


January 16, 2013  2:29 PM

UK PowerShell group – 29 January 2013

Richard Siddaway Richard Siddaway Profile: Richard Siddaway


When: Tuesday, Jan 29, 2013 7:30 PM (GMT)


Where: virtual

*~*~*~*~*~*~*~*~*~*

Active Directory is one of the commonest automation targets for administrators. This session will covert the basics of automating your AD admin – scripts and the Microsoft cmdlets. The new features in PowerShell for Windows 2012 AD will also be covered

Notes


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: RCRWH3
    Entry Code: 5p7$}S_!h
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.


January 16, 2013  12:18 PM

PowerShell wins award

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell has won one on InfoWorld’s Technology of the Year awards for 2013

See http://www.infoworld.com/slideshow/80986/infoworlds-2013-technology-of-the-year-award-winners-210419#slide24

for details


January 16, 2013  11:02 AM

Workflow article 4

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The next in the series of articles on PowerShell workflows that are appearing on the Scripting Guy blog has been published.

The articles in the series that have been published are:

http://blogs.technet.com/b/heyscriptingguy/archive/2012/12/26/powershell-workflows-the-basics.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/02/powershell-workflows-restrictions.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/09/powershell-workflows-nesting.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/16/powershell-workflows-job-engine.aspx

Look for the next article in one weeks time.

Until then Enjoy!


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: