I must say I was a little puzzled when reading description for this event. For me the main issue in this even is the lack of information about DHCP server. I assumed this is Windows 2012 (same as Hyper-V host), but I can’t find it anywhere in event description (I may be tired though and simply missed it). To be honest: we are not event told that DHCP server runs on Windows.
Why do I assume Windows 2012 than? Well, for me it is hard to imagine that beginners should figure out a way to query older server. I would probably try to get information using arp.exe (as bad as it sounds) but alternatives seem worse than that. So: Windows 2012. With DHCP module on it. Sweet.
But to be honest the way I would do it (if I wasn’t forced to query DHCP)? Ask Hyper-V:
But we can’t use it, so we are asking DHCP server for MAC addresses, pulled from file or passed via pipeline:
#requires -version 3.0 param ( $Base, [Parameter( ValueFromPipeline, Mandatory )] $MAC ) process { $IP = (Invoke-Command -Session $Session { Get-DhcpServerv4Lease -ScopeId 10.0.0.0 -ClientId $using:MAC }).IPAddress }
Some validation for MAC address would be probably good idea – but we’ve done enough of the regex magic in previous tasks to know how to do it. Where did $Session come from? Well, if I want to check 100s of MACs, I want to connect to DHCP server once. I define this session and credentials in begin block:
begin { $DomainCred = New-Object pscredential -ArgumentList ( 'monad\admin', (ConvertTo-SecureString -AsPlainText -Force P@ssw0rd) ) $LocalCred = New-Object pscredential -ArgumentList ( '.\Administrator', (ConvertTo-SecureString -AsPlainText -Force P@ssw0rd) ) Set-Item WSMan:\localhost\Client\TrustedHosts -Concatenate -Value 10.* -Force $Session = New-PSSession -Credential $DomainCred -ComputerName DHCP1 $Counter = 1 }
As you can see – I’m trying to avoid issues with remoting also for newly created VMs. Why, you may ask? Add-Computer accepts –ComputerName and works fine remotely! Right? Well… sort of. You probably heard that remoting works on Server Core 2012 by default? So does CIM via WSMan. What about WMI? We can try:
It’s possible that firewall on target box will not be configured same as default, but I guess it’s good idea to check both options. I went with Windows 2012 scenario, but in real world – there would be some error handling involved and trying both ways. In my “short” solution I just use PowerShell Remoting for adding computer to domain, and Restart-Computer (that luckily supports –Protocol parameter) to reboot the box:
$NewName = "$Base$Counter" Invoke-Command -ComputerName $IP -ScriptBlock { Add-Computer -NewName $using:NewName -Force -DomainName monad -DomainCredential $using:DomainCred } -Credential $LocalCred Restart-Computer -Protocol WSMan -ComputerName $IP -Credential $LocalCred -Force $Counter++
Many of you probably will ask: why didn’t you use workflow? Well, the answer is pretty simple: it does not look like real workflow task. What do I mean by that? I was told by smart people from Microsoft that workflow is perfect solution when problem is:
- multi-machine (2… partially checked)
- long-running
- require checkpoint/ persistance
- need asynchronous, restartable, parellizable or interruptible (partially checked)
If I would need to start from bare-metal (or vanilla VM), install OS, add it to the domain, install roles on it, configure these roles – than yes, workflow would be my first choice. Here? I could, but I would feel like I’m hunting a fly with a cannon.