Thursday, March 29, 2012

Windows 8 Hyper-V objects are aLive

For those folks new to PowerShell you need to wrap your brain around the object concept.  It is fundamental to understanding (grok-ing actually) tons of stuff.

In the Hyper-V cmdlet set in Windows 8 if you ‘get’ a VM object  (  $vm = Get-VM –Name Foo) you can simply type of object out and see its properties ( $vm ).

PS C:\Users\Administrator> $vm

Name                    State CPUUsage(%) MemoryAssigned(M)

----                    ----- ----------- -----------------
BrianEhDC.BrianEh.local Off   0           0


Now, lets say that Admin Joe or XenDesktop brokering  just turned on that VM that you have captured as your object.  Type its properties again.

PS C:\Users\Administrator> $vm

Name                    State   CPUUsage(%) MemoryAssigned(M)
----                    -----   ----------- -----------------
BrianEhDC.BrianEh.local Running 4           512

Notice that it is now running.  And you didn’t have to re-query to get that.

As stated by the Feature lead for the Hyper-V cmdlets:  “You get it for free” – In other words you didn’t have to do extra work to see that a property changed.  You did not have to do Get-VM again.


Friday, March 23, 2012

Server 2012 on the Acer PDC Laptop with Hyper-V

This is all about getting Hyper-V working on a laptop when SLAT is not available on your hardware.  Because not all of us can afford a new shiny laptop to support Client Hyper-V.

Now, here is the big warning;

This is Server, not Client – In the end, the experience is nearly identical.

This is a computer with Hyper-V running (it has –V or –VT on the chipset).  It works, but if you want the fancy Windows 8 Client experience, you will not get it here.

There is also an order to adding the Roles and Features.  This is not rocket science, just proper ordering.

Now, I did add an SSD to my PDC laptop and I am incredibly happy I did.

  1. Install Windows Server 8
  2. Get the needed drivers from the Acer website (the display will be horrible, the disk will be slow) -
    1. Intel Chipset driver
    2. Intel VGA driver (this is the only driver that is necessary)
    3. and you might need the wireless LAN driver (the wired NIC is definitely in the installer)
    4. I also grabbed the audio driver
  3. Get that all working and patch the machine.
  4. Add the following Features:
    1. Wireless LAN Service
    2. Media Foundation
    3. User Interfaces and Infrastructure
      1. Desktop Experience
    4. reboot
  5. Now you can add the Hyper-V Role
  6. If you need sound, be sure to enable the Windows Audio service (set it to automatic and start it if you need it right away)

Now you have your PDC Laptop – still useful – running Server 8 Hyper-V.

You can fully play with all the new PowerShell commands.  (well, isn’t that why you would want to do this!)

If you want the Marketplace, then you need to create a user account as you cannot use the built-in local administrator to access the marketplace.  Otherwise, it is all there – touchscreen, Metro experience, etc..

Monday, March 19, 2012

Handy PowerShell tasks for Hyper-V in Windows 8

Okay, so you have committed yourself to learning how to use PowerShell and you have the Windows 8 Server Beta.

You don’t want to write all kinds of fancy scripts, you just want to do the same tasks that you did in the GUI.  And for increased pain (forced learning) you even installed Server Core or Hyper-V Server.

Here are a few of those good old one-off type of actions that we have grown used to, but using PowerShell to drive them.

This should introduce you to doing tasks using PowerShell as well as getting started with the Hyper-V cmdlets.

Create a new VM:

New-VM or

New-VM –Name “DemoVM” or

New-VM -Name "DemoVM" -MemoryStartupBytes 2gb -bootdevice HardDrive -SwitchName Lab -path C:\users\public\documents -NewVHDSizeBytes 36gb –NewVHDPath C:\users\public\documents\DemoVM

Insert an ISO into the virtual DVD drive:

Set-VMDvdDrive –VMName DemoVM -Path C:\users\public\Documents\DemoOSInstaller.iso

Boot the VM:

Start-VM –Name DemoVM

Launch a VMConnect VM Console (after all you have a clean OS to install and all you have is the beta ISO):

vmconnect localhost DemoVM

Eject the DVD from the virtual DVD drive:

Set-VMDvdDrive –VMName DemoVM -Path $NULL

Friday, March 16, 2012

Linking a VM and a Virtual Switch with PowerShell and Windows 8

So far I have discovered a physical NIC of my Hyper-V Server and created an External Virtual Switch (Have I ever mentioned how happy I am that MSFT calls them Virtual Switches now!?)

I have not blogged about creating a New-VM – frankly it is super simple.  Just type New-VM with no parameters and you have a VM.

If you do this you have a New Virtual Machine and all Hyper-V VMs have a Network Adapter by default. 

This kind of dictates the Verb that we use.  Since there is one we won’t Add, we need to change properties.  So we Get and then Set.  Or if you are feeling brash just Set.

The traditional way (the way I learned in .Net programming class) to make a change without causing extra harm is to Get, change your setting, and Set. 

Wait, hold the phone.  That does not apply here.  There is a Verb we don’t see much.  Connect.

Using Get-VMNetworkAdapter -VMName New* I get the vNIC of the VM.  And I need to capture that to an object.

$vmNic = Get-VMNetworkAdapter -VMName New*

In my last article I created a VMSwitch named “VMs”.  This is what I need to attach the VM to.  I cannot just modify the $vmNic.SwitchName, this is a ReadOnly property.

Connect-VMNetworkAdapter -VMNetworkAdapter $vmNic -SwitchName VMs

And, it is pretty flexible.  I fed in the VM vNIC object using –VMNetworkAdapter.  But I could also have used the –VMName (if it only has one vNIC) or pass in the VMSwitch object using –VMSwitch instead of –SwitchName

Also, New-VM also allows you to define a -SwitchName at creation time.  But that is not as universally applicable.

Thursday, March 15, 2012

Creating an External Virtual Switch in PowerShell and Windows 8

In a previous post I spent a lot of time trying to discover my physical NIC.

That was all leading up to this post.

Now, we need the Hyper-V cmdlets at the front:  Get-Command –Module Hyper-V and I want to create a new VM Switch so the cmdlet is New-VMSwitch.

New-VMSwitch needs a couple very basic pieces of information.  All of which we have seen in the GUI (Name, allow management OS, NetAdapterName, SwitchType, etc.

I need an Interface Name or Interface Description.  This is fine If I know what those are.  I can get that from Get-NetAdapter.

But, in my previous post I wanted to select the IP subnet that the NIC is attached to.

If I use this: Get-NetIPAddress –IPv4Address 10* | Get-NetIPInterface to return the NetIPInterface object to me based on a selection of the IPAddress starting with 192

I can used the returned NetIPInterface to then feed in to the Interface name or description of the New-VMSwitch cmdlet.

$if = Get-NetIPAddress –IPv4Address 192* | Get-NetIPInterface

The property ifAlias is the same as the NetAdapterName that New-VMSwitch is looking for.

New-VMSwitch –NetAdapterName $if.ifAlias -Name VMs

If you want to enable SR-IOV then you add the true at the end – you can only do this when you create a switch.

New-VMSwitch -NetAdapterName $if.ifAlias -Name VMs -EnableIov $true

Now, be aware of something.  The default behavior is to allow the Management OS to share this switch, so if you don’t want that to happen you have to be explicit about it.

New-VMSwitch -NetAdapterName $if.ifAlias -Name VMs –AllowManagementOS $false

Wednesday, March 14, 2012

James Whittaker is back at Microsoft

For those of you not in the software testing circles this might not mean much to you.

James Whittaker is one of the pre-eminent folks in the field of software testing. 

It was sad a couple years ago when he suddenly left Microsoft for Google.  And interestingly enough he is back at Microsoft.

Most test folks are outspoken and critical.  Maybe that is what makes a good tester(?)  We call it as it is, trying to be accurate and factual.

There was one classic blog article that James wrote that I always loved and still see the symptoms of all over the world of software:

The title speaks for itself.

If you are interested, James has a new blog and he opens right up with a post critical of Google:

If you didn’t notice his blog names; back in the day is was JW_On_Test and today it is JW_On_Tech.

Finding a physical network adapter with PowerShell in Windows 8


Okay, done.  That was a bit lackluster, wasn’t it?

First of all, try this:  Get-Command –Module NetAdapter
Okay, lots of cmdlets.  Recall all those intricate levels to netsh?  It is all here:  Get-Command –Noun Net*  but I only want to look at the physical NIC of the operating system.

Lets examine a Network Adapter object to determine what we can select on.

$nic = Get-NetworkAdapter (I am assuming that you only have one, if you have more than one $nic becomes an array and that changes inspection a bit)

If I type $nic I get (Name, InterfaceDescription, ifIndex, MacAddress, LinkSpeed):

Okay, but there are more properties.  Try this: $nic | Format-List

Okay, a bit more.  But there are actually more properties than that.  You will see this if you type $nic. and then hit TAB a bit.  Lots of properties.  Or:  Format-List –InputObject $nic –Property *

So, what can I select on here?  Name, Description, MAC, Up or Down or Connected, Link Speed.  Properties of the physical NIC adapter.  But I want to select a NIC based on the network it is attached to, where it this?

Lets go back to our list of Network cmdlets.  I see Get-NetIpAddress and Get-NetIpInterface.  Hmm..  I list those out and I see all kinds of stuff.  Loopback adapters, physical adapters, missing adapters.  Must be everything that is configured.

If I Get-NetIPInterface –Interface Wired* –ConnectionState Connected I filter down to those interfaces that are physically connected.

From here I see that I have an interface for the IPv6 address and an interface for the IPv4 address.  And they have the same ifIndex (physical NIC device).  But I am still stuck as the physical device and nothing with the DNS of the network or the IP or subnet that came from DHCP.  But, I have the ifIndex.

Lets capture that NetIPInterface object $nic = Get-NetIPInterface –Interface Wired* –ConnectionState Connected

Let’s focus on Get-NetIPAddress   If I Get-NetIPAddress I can select (or filter) using IPv4Address, Alias (Name), InterfaceAlias (the discovered DNS), and InterfaceIndex.  Yea!

Now, what are the IP addresses associated with this interface:  Get-NetIPAddress –InterfaceIndex $nic.ifIndex

I got both an IPv6 and IPv4 back and the Name, Preferred, and that it came from DHCP.  So, I could have selected here and went the other way to the interface as well.

Getting a bit more advanced and linking these two selection criteria together.

Get-NetIPAddress –IPv4Address 192* | Get-NetIPInterface


Get-NetIPInterface | Get-NetIPAddress –IPv4Address 192*

The difference is the object you get back.  In the first one I get the Interface object as my result.  With the second one I get the IP Address object as the result.

I could also select my NICs using Get-NetAdapter.  For example the Intel NICs are always for VMs and I only want a physical NIC.

Get-NetAdapter -InterfaceDescription *Intel* –Physical

I can feed my other return into this to verify that what I got back also meets this criteria or compare the InterfaceIndex that was returned by both.  This way I know if the cable guys have a patch or port incorrect.

Tuesday, March 13, 2012

Hyper-V cmdlets built in to Windows 8

One of the big criticisms of Hyper-V to date is that if you install the Free edition “Hyper-V Server” you do the whole; “okay, now what?”

Oh, I need to manage it remotely?  Oh, it is a royal pain if it is not domain joined?

Well, Microsoft heard you.  And in Windows 8 there is a complete set of PowerShell cmdlets for Hyper-V to save your day.

You can get a video tour here:

Or, you can add the Hyper-V cmdlets Feature to any Windows 8 system (Server and Client) and type; 

Get-Command –Module Hyper-V

and see the vast array of cmdlets that you have.  Everything you could do in the Hyper-V Manager and more.

Monday, March 12, 2012

Monitoring SCVMM New-SCVirtualMachine Jobs

I see this question frequently in the SCVMM forum. 
A job was started and I attempted to perform some action and the VM is not ready.  One way SCVMM lets you handle things like this is through JobGroups.  But not all cmdlets support JobGroups and instead you ( as the coder ) must ‘do the right thing.’
In the forums I have made a feeble attempt to relate monitoring WMI / CIM job status to monitoring the SCVMM job progress.
Well, I had a need to write a VM deployment script, so I thought that I would tackle this topic once and for all.  As it is different than WMI jobs.
In the WMI / CIM world you send off a command and get a response back.  Usually within that is the ReturnValue.  If this is ‘0’ then the task is done, if this is ‘4096’ then the task is running, if it is anything else something went wrong.
In PowerShell we are so very used to getting an object back that we rarely take the time to actually look at it, or the process behind it.  We get the object back and we move on.
And this is not always a good thing to be doing.  There are cases where need to make sure that whatever we asked to happen actually finished before we move on.
Using the New-SCVirtualMachine cmdlet will pretty quickly give you a VM object back.  But if you then turn to the Job console in the GUI you will see that there is a bunch of stuff happening.  How do you know when this is complete?
$vm = New-SCVirtualMachine <…>
Well, lets take a look at that object we get back from New-SCVirtualMachine.
VMCPath                             : C:\Users\Public\VMs\ViewRds1\Virtual Machines\FD4E85BB-A9EC-4E20-9A45-7BC94B2189D5.xml
MarkedAsTemplate                    : False
OwnerSid                            :
VMId                                : FD4E85BB-A9EC-4E20-9A45-7BC94B2189D5
VMResourceGroup                     :
VMConfigResource                    :
VMConfigResourceStatus              : ClusterResourceStateUnknown
VMResource                          :
VMResourceStatus                    : ClusterResourceStateUnknown
DiskResources                       : {}
UnsupportedReason                   : Success (0)
RefresherErrors                     : {}
VirtualMachineState                 : PowerOff
HostGroupPath                       : All Hosts\ViewRds1
TotalSize                           : 8497528832
MemoryAssignedMB                    : 1024
MemoryAvailablePercentage           :
DynamicMemoryDemandMB               :
DynamicMemoryStatus                 :
AllocatedGPU                        :
HasPassthroughDisk                  : False
Status                              : UnderCreation
HasSavedState                       : False
StatusString                        : Creating...
StartAction                         : NeverAutoTurnOnVM
StopAction                          : SaveVM
RunGuestAccount                     :
DelayStart                          : 0
CPUUtilization                      : 0
PerfCPUUtilization                  : 0
PerfMemory                          : 0
PerfDiskBytesRead                   : 0
PerfDiskBytesWrite                  : 0
PerfNetworkBytesRead                : 0
PerfNetworkBytesWrite               : 0
VirtualizationPlatform              : HyperV
ComputerNameString                  : ViewRds1.pvs.brianeh.local
CreationSource                      : ViewRdsHost
IsUndergoingLiveMigration           : False
SourceObjectType                    : VM Template
OperatingSystemShutdownEnabled      : True
TimeSynchronizationEnabled          : True
DataExchangeEnabled                 : True
HeartbeatEnabled                    : True
BackupEnabled                       : True
ExcludeFromPRO                      : False
FailedJobID                         : 875de483-5160-4e66-8884-ec29885a2ebb
CheckpointLocation                  :
SelfServiceUserRole                 :
PassThroughDisks                    : {}
ComputerTier                        :
UpgradeDomain                       :
SCApplications                      : {}
LastRestoredVMCheckpoint            :
ComplianceStatus                    :
IsFaultTolerant                     : False
DeploymentErrorInfo                 :
ServiceDeploymentErrorMessage       :
DeploymentState                     : Undeployed
TieredPerfData                      : e26928de-370b-4751-9c7e-020b09647bc1
Location                            : C:\Users\Public\VMs\ViewRds1
CreationTime                        : 2/15/2012 11:08:55 AM
OperatingSystem                     : 64-bit edition of Windows Server 2008 R2 Enterprise
HasVMAdditions                      : False
VMAddition                          : Not Detected
NumLockEnabled                      : False
CPUCount                            : 2
IsHighlyAvailable                   : False
LimitCPUFunctionality               : False
LimitCPUForMigration                : False
Memory                              : 1024
DynamicMemoryEnabled                : True
DynamicMemoryMaximumMB              : 8096
DynamicMemoryBufferPercentage       : 20
MemoryWeight                        : 5000
VirtualVideoAdapterEnabled          : False
MonitorMaximumCount                 :
MonitorResolutionMaximum            :
BootOrder                           : {CD, IdeHardDrive, PxeBoot, Floppy}
ComputerName                        : ViewRds1.pvs.brianeh.local
UseHardwareAssistedVirtualization   : False
SANStatus                           : {DeployVMMultipleVolumeOnVMDisk (1212)}
CostCenter                          :
QuotaPoint                          : 1
IsTagEmpty                          : False
Tag                                 : (none)
CustomProperties                    : {, , , ...}
CustomProperty                      : {}
UndoDisksEnabled                    : False
CPUType                             : 3.60 GHz Xeon (2 MB L2 cache)
ExpectedCPUUtilization              : 20
DiskIO                              : 0
NetworkUtilization                  : 0
RelativeWeight                      : 100
CPUReserve                          : 0
CPUMax                              : 100
VirtualDVDDrives                    : {ViewRds1}
VirtualHardDisks                    : {ViewRdsTempl.vhd}
VirtualDiskDrives                   : {ViewRds1}
ShareSCSIBus                        : False
VirtualNetworkAdapters              : {ViewRds1}
VirtualFloppyDrive                  : ViewRds1
VirtualCOMPorts                     : {COM1, COM2}
VirtualSCSIAdapters                 : {ViewRds1}
CapabilityProfile                   :
CapabilityProfileCompatibilityState : Compatible
VMCheckpoints                       : {}
HostId                              : fa18d24c-7cbb-4244-999b-1dd26d7d2969
HostType                            : VMHost
HostName                            : threel6.pvs.brianeh.local
VMHost                              : threel6.pvs.brianeh.local
LibraryServer                       :
Cloud                               :
LibraryGroup                        :
GrantedToList                       : {}
UserRoleID                          : 75700cd5-893e-4f68-ada7-50ef4668acc6
UserRole                            : Administrator
Owner                               : PVS\Administrator
ObjectType                          : VM
Accessibility                       : Public
Name                                : ViewRds1
IsViewOnly                          : False
Description                         :
AddedTime                           : 2/15/2012 11:08:55 AM
ModifiedTime                        : 2/15/2012 11:15:12 AM
Enabled                             : True
MostRecentTask                      : Create virtual machine
ServerConnection                    : Microsoft.SystemCenter.VirtualMachineManager.Remoting.ServerConnection
ID                                  : e269288b-370b-4751-9c7e-020b09647bc1
MarkedForDeletion                   : False
IsFullyCached                       : True
ServicingWindows                    : {}
I highlighted a couple items that are important to avoiding sending a command before an existing one is finished.
Now, it gives us this MostRecentTask, lets look at that.
Name                 : Create virtual machine
Description          : Create virtual machine
Progress             : 32 %
Status               : Running
CmdletName           : New-SCVirtualMachine
ErrorInfo            : Success (0)
StartTime            : 2/15/2012 11:08:54 AM
EndTime              :
Owner                : PVS\Administrator
ErrorInfo            : Success (0)
AdditionalMessages   : {}
ResultName           : ViewRds1
ResultObjectTypeName : Virtual Machine
IsStoppable          : True
IsRestartable        : False
If you notice, this is the actual Create Virtual Machine job.  This gives you a quick link direct to the current long running task.
You also have the cmdlet that invoked the job. 
One thing to be aware of is that this MostRecentTask reference has a life to it.  At some point in the future, this reference will be NULL as the last job has aged and there is no reason to keep the reference any longer.
Now, you could monitor that MostRecentTask for completion.  Or you could monitor the status of the VM itself.
$vm.MostRecentTask.Status = Completed
or cast it to a new object to get the job itself and then query the job;
$job = $vm.MostRecentTask
Get-SCJob $job
As a recent forum user put it:
A simple line of:
ifelse { [string]($vm.MostRecentTask | select "Status") -match "Running" {
  "Skip this VM, it is already running a job"

Should handle what I need.

Friday, March 9, 2012

Windows 8 Beta–the platform comes together

I know I am bit late to the party, but if you have not done it already – you NEED to download the Win8 Server Beta.

Notice that “8” is written just that way.  With the parenthesis.

Windows Server 8 has lots of little new features.  Each on its own does not mean much, but bringing them all together makes for some really cool stuff.

For example: 

SMB 2.2 – to most of us the enhancements mean little other than a more reliable SMB protocol.  And since Windows is the main user of CIFS (the other name for SMB) then it also means nothing to non-CIFS customers.  However, its enhancements enable:

The HA File Server – okay, this is on feature that has been necessary for a long time.  Take the File Server Role and make it an active / active Failover Cluster.  Oh, to do that you needed:

Enhancements for Cluster Shared Volumes and Clustering in general.  Lots of little things here but they all add up to a big win for the platform as a whole.  Primarily, CSV moving to CSVFS – the v1 of the cluster file system.

Take those together and now you have a resilient, highly available File Server that you can use for VHDX / VHD storage behind Hyper-V, and SQL database storage (whoa) behind SQL.

This also enables the Hyper-V Live Migration without shared storage scenarios and migration of VMs in a checkout type of mode.  Such as from your test client to the share then to your development client.

Just a dusting of the features and how they align with each other to make a bigger platform package beyond the single Roles.

Oh, PowerShell everything..  More coming on that.  Lots to consume there.  If you don’t grok PowerShell yet, time to begin learning.  You can learn some coding basics at (go do it!).

Tuesday, March 6, 2012

Applying SCVMM 2012 Logical network assignment with PowerShell

This is a little script that I needed to write in order to quickly set up a test environment of mine.

One thing that I am going to do here is contrast what I did with what the SCVMM view script gave me.

The known issues at hand:

I have a logical network.  I have a large number of hosts that all need to be associated with this logical network.  I have to find the correct NIC (as a logical network is associated with the hardware NIC, not with a virtual network, so it is always an External Virtual Network).

Here is what I have:

$vmHost = Get-SCVMHost

foreach ($e in $vmHost) {
    $vmHostNetworkAdapter = Get-SCVMHostNetworkAdapter -VMHost $e | where {$_.IPAddresses -match "10.233.40"}

    $logicalNetwork = Get-SCLogicalNetwork -Name "Shared"
    $JobGroupID = [System.Guid]::NewGuid().ToString()

    Set-SCVMHostNetworkAdapter -VMHostNetworkAdapter $vmHostNetworkAdapter -AddOrSetLogicalNetwork $logicalNetwork -JobGroup $JobGroupID

    Set-SCVMHostNetworkAdapter -VMHostNetworkAdapter $vmHostNetworkAdapter -AvailableForPlacement $true  -JobGroup $JobGroupID

    Set-SCVMHost -VMHost $e -JobGroup $JobGroupID -RunAsynchronously

Breaking it down:

  • I get the all the host objects.
  • I query for the physical NIC, selecting on the IP address that it has (I want the logical network in this IP range).
  • I get the logical network object. (previously created manually)
  • Then I assign the Logical network to the NIC.
  • I also enable placement.

I could have selected on different parameters to find the proper NIC of the Hyper-V Server to create the Logical Network on.

A particular SCVMHostNetworkAdapter has the following properties:

Name                           : Intel(R) 82579LM Gigabit Network Connection
IPAddresses                    : {, fe80::b428:524d:463:3ce0}
DHCPEnabled                    : True
IPSubnets                      : {, fe80::/64}
DefaultIPGateways              : {}
MacAddress                     : 18:03:73:D2:53:4C
PhysicalAddress                : 18:03:73:D2:53:4C
NetworkLocation                : Shared
VirtualNetwork                 : Shared
VLanTags                       : {0}
UsableVLanTags                 : {0}
VLanMode                       : Access
DesiredVLanMode                : Access
VLanEnabled                    : False
ConnectionState                : Connected
ConnectionName                 : Local Area Connection 3
Description                    :
PrimaryDNSSuffix               :
MaxBandwidth                   : 1000
VMHost                         : threel5.pvs.brianeh.local
LogicalNetworkMap              : {[Shared, System.Collections.Generic.List`1[Microsoft.SystemCenter.VirtualMachineManager.SubnetVLan]]}
UsableVlanMode                 : Access
ModelAccessibleSubnetVLans     : {[Shared, System.Collections.Generic.List`1[Microsoft.SystemCenter.VirtualMachineManager.SubnetVLan]]}
LogicalNetworks                : {Shared}
SubnetVLans                    : {}
UnassignedVLans                : {}
AvailableForPlacement          : True
UsedForManagement              : True
LogicalNetworkCompliance       : Compliant
LogicalNetworkComplianceErrors : {}
BDFLocationInformation         : PCI bus 0, device 25, function 0
ServerConnection               : Microsoft.SystemCenter.VirtualMachineManager.Remoting.ServerConnection
ID                             : fcb44659-06ca-44e8-9932-c9488897437a
IsViewOnly                     : False
ObjectType                     : VMHostNetworkAdapter
MarkedForDeletion              : False
IsFullyCached                  : True

For me it made sense to select on the following:

IPAddresses : {, fe80::b428:524d:463:3ce0}


IPSubnets : {, fe80::/64}

But you could select on any of the properties of the object.  A bit of background;

In SCVMM the Logical Network is associated with a physical NIC. For the same reason that I selected on the IP. It is a way to tie the VM to the physical topology of your network. So you always end up on the same subnet.

This gets around historic Windows behavior of not always ordering the NICs the same as they are in the chassis. You never can guarantee a relationship between the physical and the ordering in the OS.

I mentioned at the top that I would also look at what the SCVMM View Script button in the wizard gave me.  I have always been critical of how verbose the View Script option is of SCVMM wizards and this is no exception.  The primary reason that I am critical is that it is hard to consume and turn into something universal, especially if you are not familiar with PowerShell.

The thing to pay attention to is where you are setting parameters of an object that already has these settings applied.  In other words, wasting cycles re-setting the exact same value.

Here is what SCVMM gave me with ‘View Script’:

$vmHost = Get-SCVMHost -ID "dcbcaa95-7627-45a1-afbe-69ff970e40ea" -ComputerName "threeb1"

$vmHostNetworkAdapter = Get-SCVMHostNetworkAdapter -Name "Intel(R) 82579LM Gigabit Network Connection" -VMHost $vmHost

# Shared
$logicalNetwork = Get-SCLogicalNetwork -ID "cee53020-cece-48f4-afea-496030292466"
Set-SCVMHostNetworkAdapter -VMHostNetworkAdapter $vmHostNetworkAdapter -AddOrSetLogicalNetwork $logicalNetwork -JobGroup "b5856f43-6539-4d68-9a0f-5ebe1241499a"

Set-SCVMHostNetworkAdapter -VMHostNetworkAdapter $vmHostNetworkAdapter -Description "" -JobGroup "b5856f43-6539-4d68-9a0f-5ebe1241499a" -VLanMode "Access" -AvailableForPlacement $true -UsedForManagement $true

Set-SCVMHost -VMHost $vmHost -JobGroup "b5856f43-6539-4d68-9a0f-5ebe1241499a" -RunAsynchronously

Breaking it down:

  • The host (hypervisor) is selected using its ID - this is the only way to guarantee you get the right host, and only one host. And is commonly used in this precise way.
  • The host network adapter is selected by name - if you spell out the entire adapter name this works, if you rename your adapters this works. Considering that there is no correlation between the NIC and the patch panel I am going with the IP range or subnet.
  • The Logical network is queried.
  • The Host network adapter is modified to apply the setting of the logical network, then it is again set to apply a description, set the vlan mode and enable for placement.
  • In my case I had already set the VLAN mode and the placement flag was on, why set them again..
  • Then the entire change job is applied to the host.
  • You will notice a JobGroup in here. A JobGroup in SCVMM is an array of commands that are executed in order from 0 to the end. Some cmdlets support it, some do not, no you need to check your cmdlets.