PowerShell for Windows Admins


July 3, 2011  6:52 AM

Computer Report IV: Time server



Posted by: Richard Siddaway
Operating System, PowerShell v2, WMI

The batch file uses

net time /querysntp

which displays the name of the Network Time Protocol (NTP) server currently configured for the local computer or the one specified in ComputerName.

Unfortunately /querysntp  has been deprecated in later versions of Windows.

In a domain we normally configure client and server machines to use the domain time synchronisation hierarchy rather than an external time source (the exception to this is the PDC emulator FSMO role holder in the root domain which is the top of hierarchy and synchronises externally)

Our test then should be to see if we are using a domain time synchronisation source or external. This information is held in the registry.

We need to look in HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\parameters.

The Type property tells us if we are using domain synchronisation (NT5DS) or and external server (NTP). The server( s ) are held in the NTPserver property.

We can amend our basic data function to read these registry keys

function get-basicdata{             
[CmdletBinding()]             
param (             
   [string]$computer="localhost"             
)             
BEGIN{}#begin             
PROCESS{            
            
Write-Verbose "Get Operating System"            
$os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer            
            
Write-Verbose "Get Computer System"            
$comp = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer            
            
Write-Verbose "Get IP Address"            
$ip = Test-Connection -ComputerName $computer -Count 1            
            
Write-Verbose "Read registry entry"            
$HKLM = 2147483650 #HKEY_LOCAL_MACHINE            
            
$reg = [wmiclass]"\\$computer\root\default:StdRegprov"            
$key = "SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\rdp-tcp"            
$value = "MinEncryptionLevel"            
$minlvl = $reg.GetDwordValue($HKLM, $key, $value)  ## REG_DWORD            
            
Write-Verbose "Create Object"            
$obj = New-Object -TypeName PSObject            
$obj |            
Add-Member -MemberType NoteProperty -Name OperatingSystem -Value $($os.Caption) -PassThru |            
Add-Member -MemberType NoteProperty -Name ServicePack    -Value $($os.CSDVersion) -PassThru |            
Add-Member -MemberType NoteProperty -Name Version       -Value $($os.Version) -PassThru |            
Add-Member -MemberType NoteProperty -Name Domain       -Value $($comp.Domain) -PassThru |            
Add-Member -MemberType NoteProperty -Name Name       -Value $($comp.Name) -PassThru |            
Add-Member -MemberType NoteProperty -Name IPv4Address -Value $($ip.IPV4Address.IPAddressToString) -PassThru |            
Add-Member -MemberType NoteProperty -Name MinEncrypt -Value $($minlvl.uValue)            
            
Write-Verbose "Read registry time entry"            
            
$key = "SYSTEM\CurrentControlSet\Services\W32Time\Parameters"            
            
$value = "Type"            
$type = $reg.GetStringValue($HKLM, $key, $value)  ## REG_SZ            
            
$value1 = "NtpServer"            
$NTPserver = $reg.GetStringValue($HKLM, $key, $value1)  ## REG_SZ            
            
switch ($type.svalue){            
 "NTP"  { $obj |            
          Add-Member -MemberType NoteProperty -Name TimeType -Value "External Server" -PassThru |            
          Add-Member -MemberType NoteProperty -Name TimeServer -Value $($NTPServer.svalue)            
         }            
 "NT5DS" { $obj |            
           Add-Member -MemberType NoteProperty -Name TimeType -Value "Domain" -PassThru |            
           Add-Member -MemberType NoteProperty -Name TimeServer -Value ""            
         }            
}            
            
$obj            
            
}#process             
END{}#end            
            
}

 

A switch statement is used to test the value of Type and the appropriate data is add to the object.

As before use

get-basicdata        

to generate output to screen or something like this

   get-basicdata | out-file basicdata.txt   

to create an output file

July 3, 2011  5:17 AM

Computer Report III: Eventlog service



Posted by: Richard Siddaway
PowerShell v2, WMI

The batch file has a separate report for event log service status

wmic service where name="EventLog" get Name, SystemName, StartMode, Status

PowerShell translation

Get-WmiObject -Class Win32_Service -Filter "Name=’Eventlog’" | Select Name, SystemName, StartMode, Status

 

This becomes a very simple function

function get-eventstate{             
[CmdletBinding()]             
param (             
   [string]$computer="localhost"            
)             
BEGIN{}#begin             
PROCESS{            
            
Write-Verbose "Get Service"            
Get-WmiObject -Class Win32_Service -Filter "Name='Eventlog'" -ComputerName $computer |             
Select Name, SystemName, StartMode, Status            
            
}#process             
END{}#end            
            
}

 

As with all of the functions we’ve seen in this series if you want the output on screen run as

get-eventstate

but if you want a file creating

get-eventstate | out-file c:\scripts\eventstate.txt


July 3, 2011  5:06 AM

Computer Report: II Service Information



Posted by: Richard Siddaway
Operating System, WMI

 

The batch file retrieves service information using

wmic service where state="Running" get DisplayName, Caption

Direct PowerShell translation is this.

Get-WmiObject -Class Win32_Service -Filter "State=’Running’" | Select DisplayName, Caption

Couple of problems:

  1. DisplayName and Caption tend to show the same output
  2. What about services that aren’t running? A major problem could be resolved if you realised a service that should be running has stopped.

Lets change the WMI to

Get-WmiObject -Class Win32_Service | sort State | Select State, Name, Caption

When we create our function we can add a switch to restrict output to just running services if required

function get-servicestate{             
[CmdletBinding()]             
param (             
   [string]$computer="localhost",            
   [switch]$running             
)             
BEGIN{}#begin             
PROCESS{            
            
Write-Verbose "Get Services"            
$services = Get-WmiObject -Class Win32_Service -ComputerName $computer            
            
if ($running){            
  $services | where{$_.State -eq "Running"} | Select Name, Caption            
}            
else {            
  $services | sort State | Select State, Name, Caption            
}            
            
}#process             
END{}#end            
            
}

 

By fetching all of the service information we allow ourselves the ability to easily modify the output if requirements change


July 1, 2011  1:56 PM

Computer report



Posted by: Richard Siddaway
Hardware, Operating System, PowerShell v2, WMI

A recent post on the powershell.com site asked about running a Windows command (batch) file through PowerShell against remote machines. The batch file was expected to produce a number of files of data in a folder structure based on computer name. This makes it difficult as we could in theory run the batch file through remoting (not actually tried it) but writing to a file share isn’t easy.

I decide to convert the batch file to PowerShell.  The first part uses a number of basic Windows commands to generate data. This function supplies exactly the same functionality

function get-basicdata{             
[CmdletBinding()]             
param (             
   [string]$computer="localhost"             
)             
BEGIN{}#begin             
PROCESS{            
            
Write-Verbose "Get Operating System"            
$os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer            
            
Write-Verbose "Get Computer System"            
$comp = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer            
            
Write-Verbose "Get IP Address"            
$ip = Test-Connection -ComputerName $computer -Count 1            
            
Write-Verbose "Read registry entry"            
$HKLM = 2147483650 #HKEY_LOCAL_MACHINE            
            
$reg = [wmiclass]"\\$computer\root\default:StdRegprov"            
$key = "SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\rdp-tcp"            
$value = "MinEncryptionLevel"            
$minlvl = $reg.GetDwordValue($HKLM, $key, $value)  ## REG_DWORD            
            
Write-Verbose "Create Object"            
$obj = New-Object -TypeName PSObject            
$obj |            
Add-Member -MemberType NoteProperty -Name OperatingSystem -Value $($os.Caption) -PassThru |            
Add-Member -MemberType NoteProperty -Name ServicePack    -Value $($os.CSDVersion) -PassThru |            
Add-Member -MemberType NoteProperty -Name Version       -Value $($os.Version) -PassThru |            
Add-Member -MemberType NoteProperty -Name Domain       -Value $($comp.Domain) -PassThru |            
Add-Member -MemberType NoteProperty -Name Name       -Value $($comp.Name) -PassThru |            
Add-Member -MemberType NoteProperty -Name IPv4Address -Value $($ip.IPV4Address.IPAddressToString) -PassThru |            
Add-Member -MemberType NoteProperty -Name MinEncrypt -Value $($minlvl.uValue)            
            
$obj            
            
}#process             
END{}#end            
            
}

All we do is make a few calls to WMI classes and we get the results into an object as shown.

To produce a file use

The contents look like this

OperatingSystem : Microsoft Windows 7 Ultimate

ServicePack     : Service Pack 1

Version         : 6.1.7601

Domain          : WORKGROUP

Name            : RSLAPTOP01

IPv4Address     : 127.0.0.1

MinEncrypt      : 2

That covers the basic data.  Need to look at services and TCP ports next


June 30, 2011  3:18 PM

PowerShell web cast by Don Jones



Posted by: Richard Siddaway
PowerShell v2

Combining Output from Multiple Sources

Webcast: Combining Output from Multiple Sources REGISTER NOW

July 6, 2011, 12pm CST

Presented by: Don Jones

Learn how easy-to-make custom objects not only let you combine output from multiple sources, but also allow you to create calculated properties and columns, customize output formatting, and easily send your output to CSV files, XML files, HTML, or pretty much anything you like.

Don Jones is the founder of ScriptingAnswers.com and the lead scripting guru at SAPIEN Technologies. He’s the author or more than twenty books on information technology, including Managing Windows with VBScript and WMI, Advanced VBScript for Windows Administrators, and Windows PowerShell: TFM. Don has written and spoken extensively about scripting and automation for years, including columns in REDMOND Magazine, MCPMag.com, Microsoft TechNet Magazine, and more, as well as a series of scripting-related Webinars for Microsoft TechNet. Don is a multiple recipient of Microsoft’s MVP Award, and one of the industry’s strongest advocates for Windows administrative automation.

Registration URL:

http://www.idera.com/Events/RegisterWC.aspx?EventID=192&s=EM_PSExpert _PSWC


June 30, 2011  3:13 PM

Scripting Guy discusses PAM modules



Posted by: Richard Siddaway
PowerShell v2, PSAM, WMI

My codeplex project publishing PowerShell Admin Modules (PAM) is discussed in this post

http://blogs.technet.com/b/heyscriptingguy/archive/2011/06/29/don-t-write-wmi-scripts-use-a-powershell-module.aspx

In particular the Get-OSInfo function from the PAMSysInfo module is heavily featured


June 30, 2011  2:19 PM

UK PowerShell Group–June 2011 PowerShell and Office – slides and scripts



Posted by: Richard Siddaway
PowerShell, User Group

As promised on the Live Meeting the slides and scripts are now available at

https://skydrive.live.com/?wa=wsignin1.0&cid=43cfa46a74cf3e96#!/?cid=43cfa46a74cf3e96&sc=documents&uc=1&id=43CFA46A74CF3E96%212924!cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212924


June 30, 2011  1:48 PM

UK PowerShell Group–July meeting advance warning



Posted by: Richard Siddaway
PowerShell, User Group

The UK PowerShell group will be presenting a Live Meeting – Tuesday 26 July 2011 @ 7.30pm BST

Subject – PowerShell Remoting

More details to follow


June 29, 2011  12:46 PM

UK PowerShell UG–30 June 2011



Posted by: Richard Siddaway
PowerShell, User Group

The rescheduled UG session (via Live Meeting) on using Office products with PowerShell is tomorrow. Details from

http://msmvps.com/blogs/richardsiddaway/archive/2011/06/21/rescheduled-ug-meeting.aspx


June 29, 2011  12:42 PM

Network Connection Ids



Posted by: Richard Siddaway
Network, PowerShell v2, Windows 2008 R2, Windows 7, WMI

Yesterday I was looking at changing a Network connection id (the name that shows in Network and Sharing Center when you look at the adapters). I kept getting an error – either COM or number of arguments depending if I was running locally or remotely.

I eventually realised that I must be using a connection id that already existed in the Registry.  I tracked them down to

HKLM:\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}

This works for Windows 7 and Windows 2008 R2. Please check for other Windows versions.

This produces a bunch of subkeys of the form

{F913D3B9-DBE4-455C-8926-10E24AB4E68A}

Each of these has a subkey Connection with a value of Name that we are interested in

function get-Registryconnectionid{             
[CmdletBinding()]             
param (             
   [string]$computer="."             
)             
BEGIN{}#begin             
PROCESS{            
            
Write-Verbose "Reading registry keys for IDs"            
$HKLM = 2147483650            
$key = "SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}"            
$reg = [wmiclass]'\\.\root\default:StdRegprov'            
$subkeys = $reg.EnumKey($HKLM, $key)            
            
            
foreach ($name in $subkeys.snames){            
  if ($name -eq "Descriptions"){Continue}            
  $conkey = "SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\$name\Connection"            
  Write-Debug $conkey            
              
  $cvalue = "Name"            
  $id = $reg.GetStringValue($HKLM, $conkey, $cvalue)  ## REG_SZ            
              
  $ivalue = "DefaultNameIndex"            
  $index = $reg.GetDwordValue($HKLM, $conkey, $ivalue)  ## REG_DWORD            
  $connection = New-Object -TypeName PSObject -Property @{            
       Index = $index.uValue            
       Connection = $id.sValue            
    }            
  $connection              
}            
            
            
}#process             
END{}#end            
            
<# 
.SYNOPSIS
Retrieves network connection ids 

.DESCRIPTION
Retrieves network connection ids held in the registry.
This includes current and previous ids.

.PARAMETER  Computer
Computer name

.EXAMPLE
get-Registryconnectionid

.EXAMPLE
get-Registryconnectionid -computer server02

#>            
            
}

This uses the standard WMI methods to read a local or remote registry

The corresponding current values are given by

Get-WmiObject -Class Win32_NetworkAdapter | select NetConnectionId, Index

The two index values are not related