PowerShell for Windows Admins


October 25, 2011  3:19 PM

Minor rant

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Why do software suppliers – Adobe with Acrobat Reader & Oracle with Java are the worst culprits – insist on trying to install their browser toolbar & change my default search engine??

What’s worse is that they make the default action to install it & I have to remember each and every time their products update – at least once a week! – to untick the box so it doesn’t install.

 

I really hate this behaviour – please stop.

I know you won’t but I had to ask

October 24, 2011  12:52 PM

Hosts file – add a record

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We’ve seen how to read the Hosts file – this is how we add a record

function add-hostfilecontent {            
 [CmdletBinding(SupportsShouldProcess=$true)]            
 param (            
  [parameter(Mandatory=$true)]            
  [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]            
  [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             
}

 

Take an IP address and computer as parameters.  Test if the hosts file exists

Read the contents, add the new record and write back.

This ensures that the new record is actually on a new line all by itself


October 24, 2011  11:49 AM

PowerShell and WMI – new MEAP release

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Four new chapters have been added to the MEAP  (early access) for PowerShell and WMI

Chapter 14 – Users and security

Chapter 15 – Logs, jobs, and performance

Chapter 16  – Hyper-V

Chapter 17 – Windows Remote Management

 

Chapter 17 deals with using WMI over the WSMAN cmdlets

 

The MEAP is available from http://www.manning.com/siddaway2/

 

The last two chapters (18&19) deal exclusively with the  CIM cmdlets and other new features in PowerShell v3


October 23, 2011  11:08 AM

Reading the hosts file

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Normally I ignore the Hosts file but my development laptop isn’t a member of my test domain – a number of reasons for this which I won’t go into.

This means that when I want to RDP to a machine in the test domain I have to use the IP address. A bit awkward but not too bad until I start changing the machines and I need to remember more IP addresses. Time to use the Hosts file then I can just refer to machine name.  First off need to be able to read the hosts file.

Could just use

Get-Content -Path C:\Windows\system32\drivers\etc\hosts

but that’s no fun.  Lets identify the bits of the file we need and junk the rest.

function get-hostfilecontent {            
 $file = Join-Path -Path $($env:windir) -ChildPath "system32\drivers\etc\hosts"            
 if (-not (Test-Path -Path $file)){            
   Throw "Hosts file not found"            
 }            
 Get-Content -Path $file |             
 where {!$_.StartsWith("#")} |            
 foreach {            
  if ($_ -ne ""){            
  $data = $_ -split " ",2            
   New-Object -TypeName PSObject -Property @{            
     Server = $data[1].Trim()            
     IPAddress = $data[0].Trim()            
   }            
  }            
 }            
}

Create the path to the file and test it exists.  I’ve used the windir environmental variable just to be sure I can find it.

Run get-content on the file and filter out the comments (start with #). For each remaining record split it in 2 based on the first space. Only allow two substrings from the split in case multiple spaces were used. Take the resultant data and output as an object with 2 properties – server name and IPAddress.


October 19, 2011  2:08 PM

Discovering NIC that has a specific IP Address

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One question (of many) that came up at that European Deep Dive (more on that later) was finding the particular network adapter associated with an IP Address.  The problem is that IP Address (in the later versions of Windows) is a string array in WMI

Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "Index=7"

returns this for the IP Address

IPAddress        : {10.10.54.202, fe80::4547:ee51:7aac:521e}

So we need a bit of magic. How can we test if an array contains a particular value?

function get-nicfromIP {            
 [CmdletBinding()]            
 param (            
  [parameter(Mandatory=$true)]            
  [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]            
  [string]$ipaddress,            
              
  [string]$computername="$env:COMPUTERNAME"            
 )            
Write-Verbose $ipaddress            
             
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $computername |            
foreach {            
 Write-Verbose "$($_.Description)"            
 if ($($_.IPAddress) -contains $ipaddress){            
  Write-Debug "getting adapter"            
              
  Get-WmiObject -Class Win32_NetworkAdapter -Filter "DeviceID=$($_.Index)" -ComputerName $computername             
 }            
}             
}

Create a function that takes an IP Address as a parameter  (thanks to Tobias for the regex – one day I’ll learn to do them)

Use the Win32_NetworkAdapterConfiguration class to retrieve the configurations. Foreach configuration test if the IPAddress array contains the IPAddress.

The –contains operator is made for this work

If our test is true then we get the Win32_NetworkAdapter that is associated with the configuration.  I’ve just used the fact that DeviceId=Index to perform the link.

Contrary to my thinking at the Deep Dive (why didn’t we test it instead of just talking about it Sad smile) there is a WMI association between the Win32_NetworkAdapterConfiguration and the Win32_NetworkAdapter  class so we could rewrite the if statement as

function get-nicfromIP {            
 [CmdletBinding()]            
 param (            
  [parameter(Mandatory=$true)]            
  [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]            
  [string]$ipaddress,            
              
  [string]$computername="$env:COMPUTERNAME"            
 )            
Write-Verbose $ipaddress            
             
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $computername |            
foreach {            
 Write-Verbose "$($_.Description)"            
 if ($($_.IPAddress) -contains $ipaddress){            
  Write-Debug "getting adapter"            
  $q = "ASSOCIATORS OF {Win32_NetworkAdapterConfiguration.Index=$($_.Index)}"            
  Get-WmiObject -ComputerName $computername -Query $q            
 }            
}             
}


October 12, 2011  1:15 PM

European Deep dive approaching

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Next Monday & Tuesday sees the first European Deep Dive  – if you are a PowerShell fan its where you need to be.

 

The speaker line up is available from

 

http://blogs.msdn.com/b/powershell/archive/2011/10/06/powershell-deep-dive-lineup.aspx

 

See you there


October 6, 2011  12:25 PM

Deep Dive line up

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The line up for this months Deep Dive has been announced

http://blogs.msdn.com/b/powershell/archive/2011/10/06/powershell-deep-dive-lineup.aspx

 

Looks good


October 4, 2011  1:27 PM

Win32_OSRecoveryConfiguration class

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The Win32_OSRecoveryConfiguration class represents the types of information that will be gathered from memory when the operating system fails. This includes boot failures and system crashes.

One very important parameter is DebugInfoType  which sets the type of debugging information written to the log file.

Possible values are:

Value Meaning

0

None

1

Complete Memory Dump

2

Kernel Memory Dump

3

Small Memory Dump

If we try and change the setting like this

Set-WmiInstance -Class Win32_OSRecoveryConfiguration -Arguments @{DebugInfoType=1}

we get this error

Set-WmiInstance : Unsupported parameter

Lets try running in an elevated prompt. Nope same error

Last chance we EnableAllPrivileges while in an elevated prompt

Nope still get same error

very last chance

Get-WmiObject -Class Win32_OSRecoveryConfiguration -EnableAllPrivileges |
Set-WmiInstance -Arguments @{DebugInfoType=1}

Now that works!!

We have to enable all privileges on the object BEFORE we try and modify it.

If you have a WMI class where you are trying to modify a property and get these errors:

  1. Try elevated prompt
  2. Try –EnableAllPrivileges in elevated prompt
  3. Try Get-WmiObject with –EnableAllPrivileges  piped into Set-WmiInstance in an elevated prompt


October 2, 2011  1:21 PM

PowerShell 3 and DHCP: scope options

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

In this post – http://msmvps.com/blogs/richardsiddaway/archive/2011/09/23/powershell-3-and-dhcp-2-scopes.aspx – we created a new DHCP scope.

Now we need to set some options on the scope. One of the main options we need to set is the DNS server

We can see the available options using

Get-DhcpServerv4OptionDefinition -ComputerName server02

This displays a list of the available options – remember that we can add our own so this isn’t necessarily a static list

The options that are set for the test scope are

PS> Get-DhcpServerv4OptionValue -ComputerName server02 -ScopeId 192.168.100.0

OptionId   Name            Type       Value                VendorClass     UserClass       PolicyName
——–   —-            —-       —–                ———–     ———       ———-
51         Lease           DWord      {86400}

The DNS server for this scope can be set like this

PS> Set-DhcpServerv4OptionValue -ComputerName server02 -ScopeId 192.168.100.0 `
-DnsServer 10.10.54.201

OptionId   Name            Type       Value                VendorClass     UserClass       PolicyName
——–   —-            —-       —–                ———–     ———       ———-
6          DNS Servers     IPv4Add… {10.10.54.201}


September 27, 2011  1:49 PM

WMI provider and MOF file

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

WMI is installed as a series of providers. The information on creating the classes comes from MOF files. I was recently asked about a problem with a specific class & could it be restored – in this case it was easier to rebuild WMI as the provider created a large part of the root\cimv2 namespace (namespaces can require multiple namespaces to complete their creation).

That got me thinking about how you discover the mof file associated with a class. Which leads to

$ns = "root\cimv2"            
$class = "Win32_Logicaldisk"            
            
            
$p = Get-WmiObject -Namespace $ns -Class $class |             
select -f 1 |             
select -ExpandProperty qualifiers |             
where {$_.Name -eq 'provider'}            
            
$class            
$p            
            
Get-ChildItem -Path C:\Windows\System32\wbem -Filter "*$($p.Value)*"

Get the first instance of a class, expand the qualifiers and select the qualifier with a name of provider.

Then perform a dir on the wbem folder to find the appropriate files. This isn’t infallible due to files names not necessarily being consistent but its a good starting point for the standard classes


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: