PowerShell for Windows Admins


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


June 28, 2011  3:48 PM

Quick Tip: Discovering service start accounts



Posted by: Richard Siddaway
PowerShell v2, WMI

Do you know which accounts are used to start the services running on your machines? if you need this information try:

Get-WmiObject -Class Win32_Service | select Name, DisplayName, StartName

For a remote machine this becomes

Get-WmiObject -Class Win32_Service -ComputerName Win7 | select Name, DisplayName, StartName

And for testing which services are started by a specific account use:

Get-WmiObject -Class Win32_Service -ComputerName Win7 | where {$_.StartName -eq ‘NT Authority\LocalService’} | select Name, DisplayName, StartName

I wanted to use a WMI filter instead of Where-Object but it didn’t want to work


June 26, 2011  12:14 PM

Monitor brightness–or not



Posted by: Richard Siddaway
Hardware, WMI

In this post

http://msmvps.com/blogs/richardsiddaway/archive/2011/06/26/1795135.aspx?CommentPosted=true#commentmessage

I discussed using WMI to check the monitor’s brightness.  Further investigation has shown that not all monitors support the interface to WMI so it is a bit of trial and error to check if it does work on your machine


June 25, 2011  12:28 PM

Read the Scripting Guy Blog



Posted by: Richard Siddaway
PowerShell v2

I had the pleasure of meeting Microsoft’s Scripting Guy, Ed Wilson and his charming wife at the recent PowerShell Deep Dive. As well as being very nice guy Ed  also has a huge depth of knowledge on scripting in general and PowerShell in particular. His Hey, Scripting Guy! blog is one of the few I read on a regular basis. I might not always agree with Ed but he makes me think about some of the things I have come to take for granted about PowerShell.

If you don’t already read this blog now would be a good time to start – Ed is just starting a series about us stopping writing PowerShell scripts!!!  http://blogs.technet.com/b/heyscriptingguy/archive/2011/06/25/don-t-write-powershell-scripts.aspx.

No, I’m not going to tell you any more – go and read it and the subscribe to the RSS feed for the rest of the posts in the series.


June 24, 2011  12:41 PM

PowerShell Basics: Loops



Posted by: Richard Siddaway
PowerShell v2

A loop is used to repeat one or more commands a certain number of times or while a condition is true.  There are a number of ways of generating a loop in PowerShell. These examples show the basic structure of each loop type.

1..10 | foreach-object {$_}            
1..10 | foreach {$_}            
            
$xs = 1..10            
foreach ($x in $xs){$x}            
            
for ($i=0; $i -le $($xs.length-1); $i++){$xs[$i]}            
            
$i = 0            
while ($i -le $($xs.length-1)){$xs[$i]; $i++}            
            
$i = 0            
do {$xs[$i]; $i++} while ($i -le $($xs.length-1))            
            
$i = 0            
do {$xs[$i]; $i++} until ($i -gt $($xs.length-1))

Foreach can be an alias of foreach-object is its on the pipeline or a command to iterate through a collection of objects if its a standalone key word

The do loop has two structures depending on how you want to test the terminating condition.

Experiment with these structures so you understand the implications.

I tend to try and use them in the following order of preference:

  • foreach-object
  • foreach (keyword)
  • for / while
  • do


June 23, 2011  3:22 PM

root\wmi–set monitor brightness



Posted by: Richard Siddaway
Hardware

Oddly the methods for changing the brightness aren’t on the WmiMonitorBrightness we get a separate class with the methods. This function can be used to set the brightness

function set-monitorBrightness {
[CmdletBinding()]
param (
[ValidateRange(5,20)]
[int]$timeout=5,
 
[ValidateRange(0,100)]
[int]$brightness
)
$monitors = Get-WmiObject -Namespace root\wmi -Class WmiMonitorBrightnessMethods

foreach ($monitor in $monitors){
  $monitor.WmiSetBrightness($timeout, $brightness)  
}    
}

 

Timeout is in seconds and is the time the change takes.  Set to 20 and watch a slow change

Brightness is the % brightness setting. The system will set the brightness to the nearest level available (see previous post)


June 23, 2011  3:16 PM

root\wmi – Monitor brightness



Posted by: Richard Siddaway
Hardware, WMI

The monitor brightness can be discovered like this

function get-monitorBrightness {

$monitors = Get-WmiObject -Namespace root\wmi -Class WmiMonitorBrightness

foreach ($monitor in $monitors){
  $brightness = New-Object -TypeName PSObject -Property @{
        CurrentLevel = $monitor.CurrentBrightness
        MaxLevel = $($monitor.Level | sort | select -Last 1)
     }
  $brightness  
}    
}

 

The WmiMonitorBrightness class is used. The level property holds the brightness levels that can be set. A simple sort ensures we get the maximum setting


June 23, 2011  12:46 PM

Testing the 4K boundary



Posted by: Richard Siddaway
Disks

Advanced Format disks have started shipping –see http://managedux.com/2011/04/26/using-vbscript-to-check-partitions-for-advanced-format-4k-512e-sector-alignment/

These disks use a 4096 byte sector instead of 512. To get the best performance from these disks the partitions have to be aligned to a 4K boundary. This happens automatically in Windows 2008 and above. 

We need to be able to start testing partition alignment. This function uses a couple of WMI classes to do just that.

function test-4KAligned {
[CmdletBinding()]
param (
   [string]$computer=".",
  
   [ValidatePattern("[A-Z]:")]
   [string]$drive
)

PROCESS{
$partitions = Get-WmiObject -Class Win32_DiskPartition -ComputerName $computer

foreach ($partition in $partitions){
 
  $query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=’$($partition.DeviceID)’} WHERE AssocClass=Win32_LogicalDiskToPartition"
  $disktopart = Get-WmiObject -ComputerName $computer -Query $query
 
 
if (($partion.StartingOffset % 4096) -eq 0){
   $align = $true
}
else {
   $align = $false
}
 
$diskpartition = New-Object -TypeName PSObject -Property @{
   Partition = $partition.Name
   Description = $partition.Description
   AlignedTo4Kboundary = $align
   Drive = $disktopart.DeviceID
}
if ($drive) {
   if ($drive -eq $diskpartition.Drive){$diskpartition}
}
else {$diskpartition}
}

}#process

<#
.SYNOPSIS
Tests disk partition alignment to 4k boundary

.DESCRIPTION
Tests disk partition alignment to 4k boundary.
See
http://managedux.com/2011/04/26/using-vbscript-to-check-partitions-for-advanced-format-4k-512e-sector-alignment/
and
http://msdn.microsoft.com/en-us/library/hh182553.aspx

Default is that all drives are tested

.PARAMETER  computer
Computer to test

.PARAMETER  drive
Drive to test

.EXAMPLE
test-4kaligned

Tests local machine

.EXAMPLE
test-4kaligned -computer server01

Tests remote machine

.EXAMPLE
test-4kaligned -computer server01 -drive C:

Tests C: drive on remote machine

#>

}

The test is performed using modulus arithmetic on the starting offset. A result of zero means its divisible exactly by 4096 so is aligned.


June 21, 2011  2:40 PM

Rescheduled UG meeting



Posted by: Richard Siddaway
PowerShell, User Group

Apologies for rescheduling with no notice but my broadband router failed tonight.


When: Thursday, Jun 30, 2011 7:30 PM (BST)


Where: Live Meeting

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

Re-scheduled – using PowerShell to automate Office including Word, Excel, OneNote, Visio and Access

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: WNGBC8
    Entry Code: k&w2kpF8d
    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.


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: