dinsdag 23 december 2014

Use a MAC address to find a specific network interface

This is an old blogpost, unpublished until now, written in 2014 when windows 2008R2 was widely used and windows 2012 was brand new. Who is stil deploying windows 2008 R2 servers? Now you can use the powershell commands on 2012R2 and 2016 to do  the same tasks.

When deploying VMs in an automated way and your VM has more than one network interface and you need to configure static IP addresses, you need to find the interface that corresponds to a specific network. I also assume you want a static IP address for a server and that your server is a Virtual Machine hosted on vCenter or Hyper-V. On that host, you configured the virtual network interface with a specific VLAN and you know the assigned MAC address. Your task is to find the corresponding interface inside the VM and configure it with the right IP configuration.

The trick is to find the interface with a specific MAC address and then configure it.  This should also work on Windows 2008 R2, so the new PowerShell CmdLets in Windows 2012 cannot be used yet.

WMI to the resque (using Get-WmiObject). Using the Win32_NetworkAdapter class and filtering on AdapterTypeId = 0 gives the list of configured ethernet adapters and the interface index I need.

$wmiResult= Get-WmiObject -Class Win32_NetworkAdapter -Namespace "root\CIMV2"
$wmiResult | Where AdapterTypeId -eq 0 | select Index,MACAddress | ft -AutoSize

Index MACAddress
----- ----------------
   10 00:50:50:A0:2D:D1
   12 00:50:50:A0:2E:D4
   14 00:50:50:A0:2F:D6

The same (and more) data is also available in the Win32_NetworkAdapterConfiguration class, except you cannot filter on 'ethernet adapters' or interface index. On the other hand, if you already know the MAC addresses of the interfaces to configure, then it might still be an option.

When you  know the interfaceindex, you can now configure the interface using netsh (2008R2) or powershell (2012 and up)

zaterdag 6 september 2014

Using .NET to convert a WMI datetime to a powershell datetime

The datetime format for WMI objects (through powershell) is different from the native powershell datetime format, so you need to convert it to PowerShell's native datetime format.

When using 'local' WMI commandlets, this is easy, just call the objects 'ConvertToDatetime' method. But when automating tasks you would collect data using powershell remoting. The powershell object containing the WMI datetime you obtained using remoting, does have all properties available, but not the methods.
You can create a local WMI object and use it's ConvertToDatetime method, but there is an easier way.

I found that solution by looking for something entirely different in this blog: New way to convert WMI time properties
Simply use [System.Management.ManagementDateTimeconverter]::ToDateTime( ) with the WMI time as the parameter.

This .Net method converts a WMI datetime to PowerShell's native DateTime format. So no need the need to create a local WMI object and then us it's conversion method :)

Example code:

$Computer = 'SERVER01'
$wmiResult = Invoke-Command -ComputerName $Computer -ScriptBlock {
 Get-WmiObject -Class Win32_OperatingSystem -Namespace "root\CIMV2"
if ($wmiResult)
    $LastBootTime = [System.Management.ManagementDateTimeconverter]::ToDateTime($wmiResult.LastBootUpTime)
    Write-Output "Server $($wmiResult.PScomputerName) with OS version $($wmiResult.Version), last booted on $LastBootTime"
    Write-Warning "Server $Computer could not be contacted through WS-Man, please check if the server is up and powershell is enabled"

If you are only interested in the last boot time and not in other properties, you can do the conversion at the remote computer (at the expense of a larger scriptblock) and just return the already converted date.