Starting up and Shutting down a list of VM’s in a specific order

A friend asked me if this was hard to do with PowerShell in Hyper-V.   He tapped me on the back and literally asked….

“When I have to shutdown a pile of Virtual servers for maintenance, I have a particular order they need to shutdown in, then startup needs to be the reverse.  Is there a nice easy way to do this in PowerShell?”

So I thought about it.   We could do this with one script actually (Which is the neat bit)

First let’s keep this simple.  I want a simple array of Servers.   We can do this in the following manner.

[array]$VMList=(‘Server1’,’Server2’,’Server3’,’Server4’)

With a list like this I can just step through them with PowerShell and Shutdown them in the order provided with a simple ForEach Loop

Foreach ($VM in $VMList)
{
Stop-VM –vm $VM
}

Now the second challenge …. REVERSING the order.  I was going to try and come up something really neat for this by getting count of elements in the array when I ran across this PowerTip from www.scriptingguys.com on Reverse an Array with PowerShell.

So to get the REVERSE order I just pass my Array into the Reverse method like this.

[array]::reverse($VMList)

Now I can run a SIMILIAR loop to Start the Virtual Machines.

Foreach ($VM in $VMList)
{
Start-VM –vm $VM
}

 

Cool.   Now I just need some way to tell the script whether I starting or stopping.   For this I can just drop in a Switch as a paramater and tell it to default to Stopping until specified.

 

param(
[switch]$Start=$True
)

 

At this point we can’t get fancy and maybe pop the $array of Servers as a parameter.   With a little IF Then Else to trap for the Switch our script looks a little like this

param(
[switch]$Start=$True,
[array]$VMlist=(‘Server1′,’Server2′,’Server3′,’Server4′,’Server5’)
)

if ($Stop)
{
    Foreach ($VM in $VMlist)
    {
    Stop-VM -VM $VM
    }
}

Else
{
    [array]::Reverse($vmlist)

    Foreach ($VM in $VMlist)
    {
    Start-VM -VM $VM
    }
}

 

Pretty neat what you can put together with just a little bit of Powershell eh?

Remember, with Great PowerShell comes Great Responsibility

Sean – The Energizedtech – Honorary Scripting Guy – MVP

MVPDays East

**** HOT UPDATE! Use Promo Code UGPROMO for FREE ENTRY ! ****

If you weren’t aware heading to Toronto, Ottawa and Montreal in the next two weeks is a Technology Roadshow called MVPDAYS.

Toronto – February 29th

Ottawa – March 2nd

Montreal – March 4th

MVPDAYS is a day filled with technology and training to help enable you in your IT or DEV career.   

There are four Tracks encompassing  ITPro, Development, Cloud and Sharepoint / Office365 will be at each city including over 20+ Speakers and Sessions.

With a little of something for everybody, it’s sure to please.

Huirry up and Register at www.mvpdays.com as spots may still be open!

if you’re a member of any of the local user groups in the Cities there’s a good chance a discount code is available!

See you there soon!

Deploy a Domain Joined Nanoserver with DeployImage Module–Part 3

Yesterday we looked at configuring a static ip address on Nano Server through the use of SetupComplete.cmd but today we’ll add in the next piece, joining a Domain.

Again, we must keep in mind two things, the early age of Nano and the fact it’s still being developed.   So we’re missing some pieces.

There is first off no directly way through the Emergency console to add this to a Domain.  In fact there is no command that creates the account in Active Directory. 

Well that’s not EXACTLY true.    Nano Server supports an Offline Domain join.

To create an offline Domain join requires three steps

  • Create the offline Join file
  • Copy the file to the workstation/server
  • Execute an offline Join with the provided file

The other method involves injecting the text from the Domain Join file into an Unattend.xml, but I haven’t have any luck with the documented process on Technet.

In this scenario we would like to join a workstation to a Domain with the following settings.

Domain     : Contoso

Computer : Contoso-Nano1

Filename   : domainjoin.djoin

On a computer which has the RSAT tools for Active Directory we need to run the Djoin.exe Command to create the file needed.   We can run this manually for the stated configuration in the following manner.

Djoin.exe /Provision /Domain Contoso /Machine Contoso-Nano1 /Savefile domainjoin.djoin

We can also run this in PowerShell by providing objects to store the information.

$Domain=’Contoso’
$Computername=’Contoso-Nano1’
$Filename=’domainjoin.djoin’
Djoin.exe /Provision /Domain $Domain /Machine $Computername /Savefile $Filename

We then copy the file over to the destination file system in some manner.    Ideally we’ll put the file into maybe the same folder as the Setup\Scripts folder.

On the destination system we would run the follow command directly to join this system to a Domain.   The nice part is you do NOT need to be on the network to make this work once the file is the destination system.

After all, this is an offline Domain join.

Djoin.exe /RequestODJ /loadfile C:\Windows\setup\scripts\domainjoin.djoin /windowspath c:\windows /localos

Now to make this work we’ll be using the same process as yesterday with SetupComplete.cmd and a HereString only we’ll be appending it to the NetSh.exe content.

$Filename=’C:\Windows\setup\scripts\domainjoin.djoin’

$SetupCompleteCMD=@”
netsh interface ipv4 set address Name=”Ethernet” static $IPAddress $Subnet $Gateway
netsh dns set dnsservers name=”Ethernet” source=static address=$DNS
djoin /requestodj /loadfile $Filename /windowspath c:\windows /localos
shutdown -f -r -t 0
“@

# Create the new one
#
Remove-Item -Path SetupComplete.cmd -Force -ErrorAction SilentlyContinue
New-Item -ItemType File -Name SetupComplete.cmd -Force | Out-Null
Add-content SetupComplete.cmd -Value $SetupCompleteCMD

Now with the Unattend.xml and the Setupcomplete.cmd in the appropriate locations if we were to inject the boot code the Nano Server will boot up, named as it should be, IP address assigned and joined to the appropriate Domain.

If you’d like a deeper look at the script performing this in action just access DeployImage from www.powershellgallery.com .

Once you install the Module (It has been tested under Windows 10 with the Windows 10 ADK installed) you can execute the following Cmdlet to get the sample scripts.

Copy-DeployImageSample

Just open up the script called DeployNanoServerVHDDomain.ps1 and have a field day.

If you have any comments or feedback please feel free to reach out at sean at powershell dot ca or submit comments, critique or pull requests on the Github source.

Cheers!

Sean
The EnergizedTech