Introduction
Links
Chapter 1 – Introduction to Virtualization and Microsoft Solutions
Links
- Hyper-V 2008 R2 Supported Guests
- Coreinfo from Sysinternals
- Automatic Virtual Machine Activation
- Windows Server 2016 Licensing Paper
- Hyper-V 2016 Supported Guests
- Linux Guest on Hyper-V Support
Videos
History of Hyper-V
Chapter 2 – Virtual Machine Resource Fundamentals
Links
Scripts
Get the worker process ID for a VM (getvmwpforvm.ps1)
(Get-WmiObject -q "SELECT * FROM Msvm_ComputerSystem WHERE ElementName = 'vmname'" -n rootvirtualizationv2).ProcessID
Enable Processor Compatibility (EnableProcessorCompatibility.ps1)
Set-VMProcessor -CompatibilityForMigrationEnabled $true
Enable Legacy Processor (EnableLegacyProcessor.ps1)
Set-VMProcessor -CompatibilityForOlderOperatingSystemsEnabled $true
View VMCX properties with PowerShell (ViewVMCXProp.ps1)
$tempVM = (Compare-VM -Copy -Path .yourvmcxfile.vmcx -GenerateNewID).VM
A number of PowerShell commands for VHDX management (VHDCommands.ps1)
#Create fixed VHDX file New-VHD -Path D:Virtualsnewfix.vhdx -Fixed -SizeBytes 10GB #To create a dynamic VHDX fi le, use this command: New-VHD -Path D:Virtualsnewdyn.vhdx -Dynamic -SizeBytes 1TB #The command to create a differencing VHDX fi le is as follows: New-VHD -ParentPath D:Virtualsnewfix.vhdx ` -Path D:Virtualsnewdif.vhdx -Differencing ` -SizeBytes 1000000000 #Here is the command to create a VHDX using very large block sizes: New-VHD –Path D:VirtualsLargeBlockSize.vhdx –BlockSizeBytes 128MB ` –LogicalSectorSize 4KB –SizeBytes 1TB #A virtual hard disk can be added to a virtual machine using the Add-VMHardDiskDrive #PowerShell cmdlet, as in this example: Add-VMHardDiskDrive -VMName Demo1 -Path D:Virtualsnewdyn.vhdx ` -ControllerType SCSI
Videos
Generation 1 vs Generation 2 VMs
Virtual Processor Configuration
Dynamic Memory
Creating a virtual disk
Chapter 3 – Virtual Networking
Links
- Port ACL Information
- Technet article on logical network design
- QOS Minimum Bandwidth Best Practices
- VMM Networking Poster
- NVGRE Specification
- VXLAN Specification
- Network Controller
- SDNv2 PowerShell Deployment
- SDN Express Information
- SDN Express Download
- SCVMM Network Controller Deployment
- SCVMM SLB Deployment
- SCVMM Gateway Deployment
- SCVMM SDNv2 Service Templates
- HNV Gateway Documentation
- SR-IOV Blogs
- Microsoft Hyper-V networking guidance
- Quality of Service Article
- Download Microsoft Message Analyzer
- Windows IT Pro article on networking with SCVMM
Scripts
Create virtual switch (CreateVirtSwitch.ps1)
#Create new external (implicit external as adapter passed) New-VMSwitch -Name "External Switch" -Notes "External Connectivity" ` -NetAdapterName "VM NIC" -AllowManagementOS $false #Create new internal (visible on host) and private (vm only) New-VMSwitch -Name "Internal Switch" -SwitchType Internal New-VMSwitch -Name "Private Switch" -SwitchType Private
Set vmNIC VLAN (setvmnicvlan.ps1)
Set-VMNetworkAdapterVlan –VMName test1 –Access –VlanId 173
Set vmNIC PVLAN (setpvlan.ps1)
#To set a VM in isolated mode, use this command: Set-VMNetworkAdapterVlan –VMName testvm –Isolated –PrimaryVlanId 100 ` –SecondaryVlanId 200 #Use this command to set a VM in community mode (note that the secondary VLAN ID sets the #community the VM is part of): Set-VMNetworkAdapterVlan –VMName testvm2 –Community –PrimaryVlanId 100 ` –SecondaryVlanId 201 #Use this command to set a VM in promiscuous mode (note that the secondary VLAN is now #a list of all VLAN IDs used in community and for the isolated): Set-VMNetworkAdapterVlan –VMName testvm3 –Promiscuous –PrimaryVlanId 100 ` –SecondaryVlanIdList 200-400 #To check the confi guration of a virtual machine, use the Get-VMNetworkAdapterVlan cmdlet, #as in this example: Get-VMNetworkAdapterVlan –VMName testvm | fl *
Create PVLAN with SCVMM (scvmmpvlanCreate.ps1)
$logicalNetwork = New-SCLogicalNetwork -Name "Production - PVLAN Isolated Mode" ` -LogicalNetworkDefinitionIsolation $true -EnableNetworkVirtualization $false ` -UseGRE $false -IsPVLAN $true $allHostGroups = @() $allHostGroups += Get-SCVMHostGroup -ID "" $allSubnetVlan = @() $allSubnetVlan += New-SCSubnetVLan -Subnet "10.1.2.0/24" -VLanID 120 ` -SecondaryVLanID 200 $allSubnetVlan += New-SCSubnetVLan -Subnet "10.1.1.0/24" -VLanID 110 ` -SecondaryVLanID 200 New-SCLogicalNetworkDefinition -Name "Lab Cloud - Production - PVLAN Isolated" ` -LogicalNetwork $logicalNetwork -VMHostGroup $allHostGroups ` -SubnetVLan $allSubnetVlan -RunAsynchronously
Create logical networks with SCVMM (scvmmlognetCreate.ps1)
$logicalNetwork = New-SCLogicalNetwork -Name "Corp" ` -LogicalNetworkDefinitionIsolation $false -EnableNetworkVirtualization $false ` -UseGRE $false -IsPVLAN $false -Description "Corporate, connected network" $allHostGroups = @() $allHostGroups += Get-SCVMHostGroup -ID "0e3ba228-a059-46be-aa41-2f5cf0f4b96e" $allSubnetVlan = @() $allSubnetVlan += New-SCSubnetVLan -VLanID 10 New-SCLogicalNetworkDefinition -Name "Corp Trunk" ` -LogicalNetwork $logicalNetwork ` -VMHostGroup $allHostGroups -SubnetVLan $allSubnetVlan -RunAsynchronously
Bulk create VLANs in SCVMM (BulkVLANCreate.ps1)
Import-Module virtualmachinemanager Get-VMMServer -ComputerName scvmm #Replace this with actual ID of the Logical Network. Get-SCLogicalNetwork | ft name, id $logicalNetwork = Get-SCLogicalNetwork -ID "1064012f-fc6a-49c4-98be-ba44914b5b8f" $startNumber = 150 $endNumber = 190 $vlanID = $startNumber do { $allHostGroups = @() $allHostGroups += Get-SCVMHostGroup -ID "0e3ba228-a059-46be-aa41-2f5cf0f4b96e" $allSubnetVlan = @() $allSubnetVlan += New-SCSubnetVLan -Subnet "10.7.$vlanID.0/24" -VLanID $vlanID $logicalNetworkDefinition = New-SCLogicalNetworkDefinition -Name "VLAN_$vlanID" -LogicalNetwork $logicalNetwork -VMHostGroup $allHostGroups -SubnetVLan $allSubnetVlan -RunAsynchronously # Gateways $allGateways = @() $allGateways += New-SCDefaultGateway -IPAddress "10.7.$vlanID.1" -Automatic # DNS servers $allDnsServer = @("10.7.$vlanID.10", "10.7.$vlanID.11") # DNS suffixes $allDnsSuffixes = @() # WINS servers $allWinsServers = @() $NewVLANName = "VLAN_" + $vlanID + "_IP_Pool" New-SCStaticIPAddressPool -Name $NewVLANName -LogicalNetworkDefinition $logicalNetworkDefinition -Subnet "10.7.$vlanID.0/24" -IPAddressRangeStart "10.7.$vlanID.10" -IPAddressRangeEnd "10.7.$vlanID.11" -DefaultGateway $allGateways -DNSServer $allDnsServer -DNSSuffix "" -DNSSearchSuffix $allDnsSuffixes -RunAsynchronously #Now create VM Network for each $vmNetwork = New-SCVMNetwork -Name "Customer_VLAN_$vlanID" -LogicalNetwork $logicalNetwork -IsolationType "VLANNetwork" -Description "VM Network for Customer VLAN $vlanID" Write-Output $vmNetwork $logicalNetworkDefinition = Get-SCLogicalNetworkDefinition -Name "VLAN_$vlanID" $subnetVLAN = New-SCSubnetVLan -Subnet "10.7.$vlanID.0/24" -VLanID $vlanID $VMSubnetName = "Customer_VLAN_" + $vlanID + "_0" $vmSubnet = New-SCVMSubnet -Name $VMSubnetName -LogicalNetworkDefinition $logicalNetworkDefinition -SubnetVLan $subnetVLAN -VMNetwork $vmNetwork #Increment the VLAN number $vlanID += 1 } until ($vlanID -gt $endNumber)
Useful Network Virtualization SCVMM (NetworkVirtualizationCommands.ps1)
Get-NetVirtualizationProviderAddress #Show the virtual network address space Get-NetVirtualizationLookupRecord | Sort-Object VMName | Format-Table CustomerAddress,VirtualSubnetID,ProviderAddress,VMName -AutoSize #View virtual network routing Get-NetVirtualizationCustomerRoute #Find MAC of next hop Select-NetVirtualizationNextHop -SourceCustomerAddress 192.168.10.4 ` -DestinationCustomerAddress 192.168.11.2 -SourceVirtualSubnetID 6864375 #Test virtual network communication Test-VMNetworkAdapter -Sender -SenderIPAddress 192.168.10.4 ` -ReceiverIPAddress 192.168.11.2 -VMName "Blue-VM-1" ` -NextHopMacAddress "00508c125f46" -SequenceNumber 100 #Create a lookup record $ProviderAddressHost="172.1.1.3" $vsid = 6864375 $DHCPClientMAC = "020203030404" New-NetVirtualizationLookupRecord -CustomerAddress 0.0.0.0 ` -VirtualSubnetID $vsid -MACAddress $DHCPClientMAC ` -ProviderAddress $ProviderAddressHost -Type L2Only ` -Rule TranslationMethodEncap
Get VMQ information (getvmqinfo.ps1)
Get-NetAdapterVmq |ft Name, InterfaceDescription,Enabled,NumberOfReceiveQueues -AutoSize
Create NIC team (createnicteam.ps1)
New-NetLbfoTeam -Name "HostSwitchTeam" -TeamMembers NICTeam3,NICTeam4 -TeamingMode SwitchIndependent -LoadBalancingAlgorithm Dynamic -Confirm:$false
Create Mgmt OS vNICs with QOS (MgmtVNicLBFO.ps1)
New-NetLbfoTeam -Name "HostSwitchTeam" -TeamMembers NICTeam3,NICTeam4 ` -TeamingMode Static -Confirm:$false New-VMSwitch "MgmtSwitch" -MinimumBandwidthMode weight ` -NetAdapterName "HostSwitchTeam" –AllowManagement $false Add-VMNetworkAdapter -ManagementOS -Name "LiveMigration" -SwitchName "MgmtSwitch" Set-VMNetworkAdapter -ManagementOS -Name "LiveMigration" ` -MinimumBandwidthWeight 50 Add-VMNetworkAdapter -ManagementOS -Name "Cluster" -SwitchName "MgmtSwitch" Set-VMNetworkAdapter -ManagementOS -Name "Cluster" -MinimumBandwidthWeight 50
Videos
SDNv2 Overview and Deployment with SCVMM
Networking and IPv4 Overview
NIC Teaming and Virtual Switch on Server
3-1 Network Configuration with SCVMM
3-2 Network Virtualization using SCVMM
3-3 HNV Gateway with SCVMM
Monitor Hyper-V Traffic
Chapter 4 – Storage Configuration
Links
Scripts
Various cmdlets for VHD[x] management (VariousVHDCmds.ps1)
#PowerShell provides an easy way to mount and unmount a VHDX fi le: Mount-VHD -Path D:Virtualsnewdyn.vhdx Dismount-VHD -Path D:Virtualsnewdyn.vhdx #Create VHDs (source option just allows data from one VHD to be copied into the new) New-VHD -Path D:Virtualsnewfix.vhdx -Fixed -SizeBytes 1000000000 New-VHD -Path D:Virtualsnewdyn.vhdx -Dynamic -SizeBytes 10GB New-VHD -ParentPath D:Virtualsnewfix.vhdx -Path D:Virtualsnewdif.vhdx -Differencing -SizeBytes 1000000000 #Convert a VHD to VHDX Convert-VHD -Path d:tempsource.vhd -DestinationPath d:tempdestination.vhdx #Resize to minimum possible size Resize-VHD .win81nondomain.vhdx -ToMinimumSize #Mount a VHD on native OS Mount-VHD -Path D:Virtualsnewdyn.vhdx #Now visible in Disk Manager, can init, create volumes etc Dismount-VHD -Path D:Virtualsnewdyn.vhdx
Storage Space management (StorageSpaces.ps1)
#Create a storage Space #List all disks that can be pooled and output in table format (format-table) Get-PhysicalDisk -CanPool $True | ft FriendlyName,OperationalStatus,Size,MediaType #Store all physical disks that can be pooled into a variable, $pd $pd = (Get-PhysicalDisk -CanPool $True | Where MediaType -NE UnSpecified) #Create a new Storage Pool using the disks in variable $pd with a name of My Storage Pool New-StoragePool -PhysicalDisks $pd –StorageSubSystemFriendlyName “Storage Spaces*” -FriendlyName “My Storage Pool” #View the disks in the Storage Pool just created Get-StoragePool -FriendlyName "My Storage Pool" | Get-PhysicalDisk | Select FriendlyName, MediaType #Create two tiers in the Storage Pool created. One for SSD disks and one for HDD disks $ssd_Tier = New-StorageTier -StoragePoolFriendlyName "My Storage Pool" -FriendlyName SSD_Tier -MediaType SSD $hdd_Tier = New-StorageTier -StoragePoolFriendlyName "My Storage Pool" -FriendlyName HDD_Tier -MediaType HDD #New-VirtualDisk –SNtoragePoolFriendlyName “My Storage Pool” –ResiliencySettingName Simple –Size 10TB –Provisioningtype Thin –FriendlyName “Documents” #Create a new virtual disk in the pool with a name of TieredSpace using the SSD (50GB) and HDD (300GB) tiers $vd1 = New-VirtualDisk -StoragePoolFriendlyName "My Storage Pool" -FriendlyName TieredSpace -StorageTiers @($ssd_tier, $hdd_tier) -StorageTierSizes @(50GB, 300GB) -ResiliencySettingName Mirror -WriteCacheSize 1GB #cannot also specify -size if using tiers and also cannot use provisioning type, e.g. Thin #Online, initialize and create volume Get-Disk | Where-Object BusType -Eq Spaces | Where-Object PartitionStyle –Eq "RAW"| Initialize-Disk -PartitionStyle GPT Get-Disk | Where-Object IsOffline –Eq $True | Set-Disk –IsOffline $False Get-Disk | Where-Object BusType -Eq Spaces | New-Partition -UseMaximumSize -DriveLetter M | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Mirror" -Confirm:$False New-Item M:Important -ItemType directory Copy-Item C:TestTest.jpg M:Important #Pin an item to SSD tier Set-FileStorageTier –FilePath M:Importanttest.jpg -DesiredStorageTier ($vd1 | Get-StorageTier –MediaType SSD) #Force an optimization to move the data to SSD tier just pinned Optimize-Volume –DriveLetter M –TierOptimize #forces the move of pinned files now. Normally this happens in the background on schedule 1am by default #View the automated optimization task Get-ScheduledTask | Where-Object TaskPath -EQ "MicrosoftWindowsStorage Tiers Management" | fl
Create SMB Share for Hyper-V (SMBShare.ps1)
MD G:VMStore New-SmbShare -Name VMStore -Path G:VMStore ` -FullAccess domainadministrator, ` domainHV01$, domainHV02$, domainHVCLUS$ #If 2012 R2 Set-SmbPathAcl -ShareName VMStore #If 2012 and this needs to be done in command prompt (replaces Set-SmbPathAcl) ICACLS G:VMStore /Inheritance:R ICACLS G:VMStore /Grant "domainadministrator:(CI)(OI)F" ICACLS G:VMStore /Grant domainHV01$:(CI)(OI)F ICACLS G:VMStore /Grant domainHV02$:(CI)(OI)F ICACLS G:VMStore /Grant domainHVCLUS$:(CI)(OI)F
Use Shared VHDX (ShardVHDX.ps1)
New-VHD -Path C:ClusterStorageVolume1SharedVHDXSavdalfcshared1.vhdx ` -Fixed -SizeBytes 25GB Add-VMHardDiskDrive -VMName savdalfc01 -Path ` C:ClusterStorageVolume1SharedVHDXSavdalfcshared1.vhdx -ShareVirtualDisk Add-VMHardDiskDrive -VMName savdalfc02 -Path ` C:ClusterStorageVolume1SharedVHDXSavdalfcshared1.vhdx -ShareVirtualDisk #To check if a virtual disk is using a shared VHDX, the SupportPersistentReservations #property can be examined. If it is set to True, then it is a shared VHDX. Get-VMHardDiskDrive -VMName savdalfc01 | ft vmname, path, ` controllertype, SupportPersistentReservations -auto
Videos
4-1 Dynamic VHDX Resize
4-2 Guest Cluster Storage Options
Storage Space Overview
Clustered Storage Spaces
Storage Spaces Direct Demo
Chapter 5 – Managing Hyper-V
Links
- Coreinfo download
- Disk2vhd download
- Nano Server Deployment
- Nano Server Image Creation
- Deploy Hyper-V host using SCVMM
- Troubleshoot Hyper-V host using SCVMM
- Configure boot from VHD
- Windows 8.1 RSAT
- Windows 10 RSAT
- Save Credentials in PowerShell Scripts
- Using Server Management Tools
- Microsoft Security Compliance Manager
- Fix Generation 2 keyboard problems
- Automatic Virtual Machine Activation keys
- Shielded VM Deployment Guide
- Microsoft orchestrator VM patching with SMA
- Microsoft Virtual Machine Converter
- Migration Automation Kit
- Datacenter Consolidation and Migration Services
Scripts
GUI to Server Core (GUI2core.ps1)
Uninstall-WindowsFeature Server-Gui-Mgmt-Infra –Restart
Server Core to GUI (core2GUI.ps1)
Install-WindowsFeature Server-Gui-Mgmt-Infra,Server-Gui-Shell –Restart
Enable Hyper-V Role (InstallHyperVRole.ps1)
Install-WindowsFeature -Name Hyper-V -Restart
Basic VM Management (VMMgmt.ps1)
#List all Hyper-V Nouns Get-Command -Module Hyper-V | Select -Unique Noun | Sort Noun #List all cmdlets for a certain Noun, in this example VM Get-Command -Module Hyper-V -Noun VM #The first cmdlet gets all virtual machines, the second part identifi es the VMs in the #Off state, and then only those VMs are passed to the fi nal cmdlet, which exports them. Get-VM | where-object {$_.State -EQ "Off"} | Export-VM -Path D:Backups #The following code just looks for XML files (which is the format #for virtual machine confi gurations) and then imports: Get-ChildItem e:virtuals*.xml -recurse | Import-VM #In another case, I wanted to configure all virtual machines that were set to automatically #start to not start if they were running when the Hyper-V server shut down. That’s easy with Get-VM | Where-Object {$_.AutomaticStartAction -eq "StartIfRunning"} |` Set-VM -AutomaticStartAction Nothing -AutomaticStopAction ShutDown
VM Group Creation (vmgroups.ps1)
#Create new VM Collection Groups New-VMGroup -Name VMCGroup1 -GroupType VMCollectionType New-VMGroup -Name VMCGroup2 -GroupType VMCollectionType New-VMGroup -Name VMCGroup3 -GroupType VMCollectionType #Add VMs to the VM Collection Groups Add-VMGroupMember -VMGroup (Get-VMGroup VMCGroup1) -VM (Get-VM VM1) Add-VMGroupMember -VMGroup (Get-VMGroup VMCGroup2) -VM (Get-VM VM2) Add-VMGroupMember -VMGroup (Get-VMGroup VMCGroup2) -VM (Get-VM VM3) Add-VMGroupMember -VMGroup (Get-VMGroup VMCGroup3) -VM (Get-VM VM4) #View the membership of the groups Get-VM | ft Name, Groups -AutoSize Get-VMGroup -Name VMCGroup2 #Perform actions on the group as if it were a VM #Enable-VMReplication -VM (Get-VMGroup VMCGroup2).VMMembers ...... Start-VM -VM (Get-VMGroup VMCGroup2).VMMembers #Create VM Management Group with VMCGroup2 and VMCGroup3 in it New-VMGroup -Name MgmtGroup1 -GroupType ManagementCollectionType Add-VMGroupMember -VMGroup (Get-VMGroup MgmtGroup1) ` -VMGroupMember (Get-VMGroup VMCGroup2) Add-VMGroupMember -VMGroup (Get-VMGroup MgmtGroup1) ` -VMGroupMember (Get-VMGroup VMCGroup3) #Create VM Management Group with VMCGroup1 and MgmtGroup1 to show nesting New-VMGroup -Name MgmtGroup2 -GroupType ManagementCollectionType Add-VMGroupMember -VMGroup (Get-VMGroup MgmtGroup2) ` -VMGroupMember (Get-VMGroup VMCGroup1) Add-VMGroupMember -VMGroup (Get-VMGroup MgmtGroup2) ` -VMGroupMember (Get-VMGroup MgmtGroup1) Get-VMGroup MgmtGroup2 | Select-Object -ExpandProperty VMGroupMembers
VM mode Sysprep (syspreppc.bat)
Sysprep.exe /generalize /oobe /shutdown /mode:VM
Module for patch injection (Install-Patch.psm1)
function Install-Patch { <# .SYNOPSIS Patches a WIM or VHD file .DESCRIPTION Applies downloaded patches to a VHD or WIM file .NOTES File Name: Install-Patch.psm1 Author: John Savill Requires: Tests on PowerShell 3 on Windows Server 2012 Copyright (c) 2013 John Savill .LINK http://www.savilltech.com .PARAMETER updateTargetPassed File (WIM, VHD or VHDX) to be patched .PARAMETER patchpath Path containing the updates .EXAMPLE Install-Patch d:filestest.vhd d:updateswin2012 Install-Patch d:filesinstall.wim:4 d:updateswin2012 #> [cmdletbinding()] Param( [Parameter(ValuefromPipeline=$false,Mandatory=$true)][string]$updateTargetPassed, [Parameter(ValuefromPipeline=$false,Mandatory=$true)][string]$patchpath) #$updateTargetPassed = "G:TempWin2012DatacenterRTM.vhdx" #or #$updateTargetPassed = "d:sourcesinstall.wim:4" #$patchpath = "D:softwareWindows 2012 Updates" if(($updateTargetPassed.ToLower().Contains(".vhd")) -eq $true) # if its VHD or VHDX. Contains is case sensitive so have to convert to lower when comparing { $isVHD = $true } else { $isVHD = $false } if($isVHD) { $updateTarget=$updateTargetPassed if ((Test-Path $updateTarget) -eq $false) #if not found { write-output "Source not found ($updateTarget)" break } else { mount-vhd -path $updateTarget $disks = Get-CimInstance -ClassName Win32_DiskDrive | where Caption -eq "Microsoft Virtual Disk" foreach ($disk in $disks) { $vols = Get-CimAssociatedInstance -CimInstance $disk -ResultClassName Win32_DiskPartition foreach ($vol in $vols) { $updatedrive = Get-CimAssociatedInstance -CimInstance $vol -ResultClassName Win32_LogicalDisk | where VolumeName -ne 'System Reserved' } } $updatepath = $updatedrive.DeviceID + "" } } if(!$isVHD) #its a WIM file { #Need to extract the WIM part and the index #extract file name and the index number $updateTargetPassedSplit = $updateTargetPassed.Split(":") if($updateTargetPassedSplit.Count -eq 3) #one for drive letter, one for folder and one for image number so would have been two colons in it c:tempinstall.wim:4 { $updateTarget = $updateTargetPassedSplit[0] + ":" + $updateTargetPassedSplit[1] #There are two colons. The first is drive letter then the folder! $updateTargetIndex = $updateTargetPassedSplit[2] $updatepath = "c:wimmount" #check if exists and if not create it if ((Test-Path $updatepath) -eq $false) #if not found { Write-Host "Creating folder " + $updatepath New-Item -Path $updatepath -ItemType directory #could have also used [system.io.directory]::CreateDirectory($updatepath) } # Mount it as folder #dism /get-wiminfo /wimfile:install.wim dism /Mount-Wim /wimfile:$updateTarget /index:$updateTargetIndex /mountdir:$updatepath } else { write-output "Missing index number for WIM file. Example: c:tempinstall.wim:4" break } } # For WIM or VHD $updates = get-childitem -path $patchpath -Recurse | where {($_.extension -eq ".msu") -or ($_.extension -eq ".cab")} | select fullname foreach($update in $updates) { write-debug $update.fullname $command = "dism /image:" + $updatepath + " /add-package /packagepath:'" + $update.fullname + "'" write-debug $command Invoke-Expression $command } $command = "dism /image:" + $updatepath + " /Cleanup-Image /spsuperseded" Invoke-Expression $command if($isVHD) { dismount-vhd -path $updateTarget -confirm:$false } else { dism /Unmount-Wim /mountdir:$updatepath /commit #dism /Unmount-Wim /mountdir:$updatepath /discard } }
Check Integration Service version of VMs (getisvmver.bat)
Get-VM | ft Name, IntegrationServicesVersion
Read guest FQDN from host (readguestfqdn.ps1)
$vmName = "savdaldc02" $vm = Get-WmiObject -Namespace rootvirtualizationv2 ` -Class Msvm_ComputerSystem ` -Filter "ElementName='$vmName'" $vm.GetRelated("Msvm_KvpExchangeComponent").GuestIntrinsicExchangeItems | ` % {$GuestExchangeItemXml = ([XML]$_).SelectSingleNode(` "/INSTANCE/PROPERTY[@NAME='Name']/VALUE[child::text()='FullyQualifiedDomainName']") if ($GuestExchangeItemXml -ne $null) { $GuestExchangeItemXml.SelectSingleNode( ` "/INSTANCE/PROPERTY[@NAME='Data']/VALUE/child::text()").Value } }
Videos
NANO Server Overview and Creation
Windows Server 2016 Top Ten Features
Inject patches to VHD or WIM
Using checkpoints for image management
Shielded VM Overview
Chapter 6 – Maintaining a Hyper-V Environment
Links
Scripts
Create a checkpoint (CreateCheckpoint.ps1)
Checkpoint-VM -Name "TestVM10" -SnapshotName "Before change"
Apply a checkpoint (ApplyCheckpoint.ps1)
Get-VM -Name "TestVM10" | Get-VMSnapshot | Restore-VMSnapshot
Resource metering examples (resourcemetering.ps1)
#To enable resource metering for a virtual machine, use this command: Enable-VMResourceMetering -VMName #To view the current measurements for a virtual machine in a detailed list format Measure-VM -VMName | fl #The metrics for a virtual machine never resets unless you either disable metering or perform #a manual reset. Use this command to perform a manual reset: Reset-VMResourceMetering -VMName #Finally, to disable the metering, use this command: Disable-VMResourceMetering -VMName #To check which virtual machines have metering enabled, run the following command: Get-VM | Format-Table Name, ResourceMeteringEnable #Get detailed metrics $report = Measure-VM -VMName savdalfs01 $report.NetworkMeteredTrafficReport $report.HardDiskMetrics
Creating a resource pool (CreateResourcePool.ps1)
New-VMResourcePool -Name GroupA -ResourcePoolType Processor New-VMResourcePool -Name GroupA -ResourcePoolType Memory New-VMResourcePool -Name GroupA -ResourcePoolType Ethernet New-VMResourcePool -Name GroupA -ResourcePoolType VHD ` -Paths @("\savdalfs01HVShare") Add-VMSwitch -ResourcePoolName GroupA -Name "External Switch" Set-VMProcessor -VMName savdal08R2 -ResourcePoolName GroupA Set-VMMemory -VMName savdal08R2 - ResourcePoolName Group A Add-VMHardDiskDrive -VMName savdal08R2 -ControllerType SCSI ` -ResourcePoolName GroupA ` -Path "\savdalfs01HVSharesavdal08R2data1.vhdx" Add-VMNetworkAdapter -VMName savdal08R2 -ResourcePoolName GroupA #Enable metering of a pool Enable-VMResourceMetering -ResourcePoolName GroupA
Videos
6-1 Hyper-V Performance Monitor View
VM Monitoring
Cluster Aware Updating
Chapter 7 – Failover Clustering and Migration Technologies
Links
Scripts
View node dynamic weight (ViewDynamicWeight.ps1)
Get-ClusterNode | ft Name, DynamicWeight -AutoSize
Add a VM service monitor (AddVMServMonitor.ps1)
Add-ClusterVMMonitoredItem -VirtualMachine savdaltst01 -Service spooler
View Cluster Network Details (ViewClusterNetwork.ps1)
Get-ClusterNetwork | ft Name, Role, AutoMetric, Metric -AutoSize
Test Cluster commands (TestCluster.ps1)
Test-Cluster -Cluster -Disk "<disk, for example Cluster Disk 5>" -Include Storage
Specify Live Migration Network (LiveMigNetwork.ps1)
Get-ClusterResourceType -Name "Virtual Machine" | Set-ClusterParameter -Name MigrationExcludeNetworks -Value ([String]::Join(";",(Get-ClusterNetwork | Where-Object {$_.Name -ne "Migration Network"}).ID))
Custom VM Move (MoveVMCustom.ps1)
Move-VMStorage -VMName -SmartPagingFilePath d ` -SnapshotFilePath -VirtualMachinePath ` -Vhds @(@{ "SourceFilePath " = "C:vmvhd1.vhdx "; ` "DestinationFilePath " = "D:VHDsvhd1.vhdx "},` @{ "SourceFilePath " = "C:vmvhd2.vhdx ";` "DestinationFilePath " = "E:VHDsvhd2..vhdx "}, ` @{ "SourceFilePath " = "C:vmvhd3.vhdx ";` "DestinationFilePath " = "F:VHDsvhd3.vhdx "}) #Check state of migrations Get-WmiObject -Namespace rootvirtualizationv2 -Class Msvm_MigrationJob| ` ft Name, JobStatus, PercentComplete, VirtualSystemName
View IP Listener for migration (ViewIPListener.ps1)
gwmi -n rootvirtualizationv2 Msvm_VirtualSystemMigrationService | select MigrationServiceListenerIPAddressList
Perform parallel Live Migrations (ParallelLM.ps1)
Workflow Invoke-ParallelLiveMigrate { $VMLIST = get-vm blank1,blank2,blank3 ForEach -Parallel ($VM in $VMLIST) { Move-VM -Name $VM.Name -DestinationHost savdalhv02 } } Invoke-ParallelLiveMigrate
Videos
Setting up Shared Nothing Live Migration
Failover Clustering in Windows Server 2016
Cluster Dynamic Quorum
Chapter 8 – Hyper-V Replica and Cloud Orchestration
Links
- Interpreting Hyper-V Replica health
- Automating Hyper-V Replica with System Center
- Azure Site Recovery
- Azure Site Recovery Capacity Planner tool
Scripts
Enable Server for Hyper-V Replica (EnableHyperVReplicaOnServer.ps1)
Set-VMReplicationServer -ReplicationEnabled 1 -ComputerName savdalhv24
View Hyper-V Replica Properties (ViewHyperVReplicaproperties.ps1)
get-vmreplicationserver -computername savdalhv24 | fl
Add Hyper-V Replica Auth Entry (AddReplicaEntry.ps1)
New-VMReplicationAuthorizationEntry -AllowedPrimaryServer -ReplicaStorageLocation -TrustGroup
Inject IP into VM (InjectVMIP.ps1)
$vmName = "win81g2" #Retrieve the Hyper-V Management Service, ComputerSystem class for the VM and the VM’s SettingData class. $Msvm_VirtualSystemManagementService = Get-WmiObject -Namespace rootvirtualizationv2 ` -Class Msvm_VirtualSystemManagementService $Msvm_ComputerSystem = Get-WmiObject -Namespace rootvirtualizationv2 ` -Class Msvm_ComputerSystem -Filter "ElementName='$vmName'" $Msvm_VirtualSystemSettingData = ($Msvm_ComputerSystem.GetRelated("Msvm_VirtualSystemSettingData", ` "Msvm_SettingsDefineState", ` $null, ` $null, ` "SettingData", ` "ManagedElement", ` $false, $null) | % {$_}) $Msvm_SyntheticEthernetPortSettingData = $Msvm_VirtualSystemSettingData.GetRelated("Msvm_SyntheticEthernetPortSettingData") $Msvm_GuestNetworkAdapterConfiguration = ($Msvm_SyntheticEthernetPortSettingData.GetRelated( "Msvm_GuestNetworkAdapterConfiguration", "Msvm_SettingDataComponent", ` $null, $null, "PartComponent", "GroupComponent", $false, $null) | % {$_}) $Msvm_GuestNetworkAdapterConfiguration.DHCPEnabled = $false $Msvm_GuestNetworkAdapterConfiguration.IPAddresses = @("192.168.1.207") $Msvm_GuestNetworkAdapterConfiguration.Subnets = @("255.255.255.0") $Msvm_GuestNetworkAdapterConfiguration.DefaultGateways = @("192.168.1.1") $Msvm_GuestNetworkAdapterConfiguration.DNSServers = @("192.168.1.10", "192.168.1.11") $Msvm_VirtualSystemManagementService.SetGuestNetworkAdapterConfiguration( ` $Msvm_ComputerSystem.Path, $Msvm_GuestNetworkAdapterConfiguration.GetText(1))
View health of VM replication (MeasureVMReplication.ps1)
Measure-VMReplication -ComputerName savdalhv21 -VMName savdalapp01 | fl
Hyper-V Replica Failover commands (ReplicaFailover.ps1)
# TEST FAILOVER #List all snapshots and perform a testfailover $VMSnapshots = Get-VMSnapshot -VMName -SnapshotType Replica Start-VMFailover -Confirm:$false -VMRecoverySnapshot $VMSnapshots[0] -AsTest #PLANNED FAILOVER #A planned failover is a bit more involved and involves running commands against the primary #VM to prepare it for failover and then activating on the replica VM. On the primary VM, #the following commands are run: Stop-VM Start-VMFailover -VMName –prepare #Next, on the replica VM, the following commands are run to actually perform the failover, #reverse the replication, and then start the replica VM. Start-VMFailover -VMName Set-VMReplication -reverse -VMName Start-VM #UNPLANNED FAILOVER $VMSnapshots = Get-VMSnapshot -VMName -SnapshotType Replica Start-VMFailover -Confirm:$false -VMRecoverySnapshot $VMSnapshots[0] #At this point, you would check that the virtual machine is in the desired state and then complete #the failover using this command: Complete-VMFailover -VMName -Confirm:$false
Videos
Setting up Hyper-V Replica
Chapter 9 – Implementing the Private Cloud, SCVMM and Microsoft Azure Stack
Links
- SCVMM Requirements
- Enable ISO Sharing for SCVMM
- Service Provider Foundation
- Windows Azure Pack
- Windows Azure Pack Evaluation Guide
- Windows Azure Pack Installation
- Windows Azure Pack IaaS Enablement
- Windows Azure Pack Deploying Gallery items
- Azure Stack Deployment Options
Scripts
Create SCVMM Private Cloud (SCVMMPrivCloudCreate.ps1)
Set-SCCloudCapacity -JobGroup "XXXXXX" -UseCustomQuotaCountMaximum $true ` -UseMemoryMBMaximum $false -UseCPUCountMaximum $false -UseStorageGBMaximum $false ` -UseVMCountMaximum $true -MemoryMB 36864 -CPUCount 40 -StorageGB 1024 $resources = @() $resources += Get-SCLogicalNetwork -Name "Hyper-V Network Virtualization PA" -ID ` "c75b66eb-c844-49a2-8bbd-83198fc8ccc0" $resources += Get-SCLogicalNetwork -Name "Lab" -ID " XXXXXX " $resources += Get-SCStorageClassification -Name "Gold" -ID " XXXXXX " $addCapabilityProfiles = @() $addCapabilityProfiles += Get-SCCapabilityProfile -Name "Hyper-V" Set-SCCloud -JobGroup " XXXXXX" -RunAsynchronously -AddCloudResource $resources ` -AddCapabilityProfile $addCapabilityProfiles $hostGroups = @() $hostGroups += Get-SCVMHostGroup -ID " XXXXXX " New-SCCloud -JobGroup " XXXXXX " -VMHostGroup $hostGroups -Name "Test Cloud" ` -Description "" -RunAsynchronously -DisasterRecoverySupported $false
Videos
VM Creation through Service Catalog
Chapter 10 – Containers and Docker
Links
- What is Docker
- Windows Containers vs Hyper-V Containers
- Check Docker installed versions
- Easily update Docker
- Install Containers and Docker on Windows Server 2016
- Solve Docker and PowerShell ISE Problems
- First actions with Containers
- Samples Website Docker file
- Add a tag to Docker image
- When images need to be rebuilt
- Docker Compose File Documentation
- Microsoft Container Documentation
- Microsoft Container Requirements
- Container Host Deployment Documentation
- Container Networking Documentation
- Docker PowerShell Module
Scripts
Videos
Overview of containers
Demo of containers
Chapter 11 – Remote Desktop Services
Links
- VDI Tuning Guide
- VDI Optimization Script for Windows 8
- Windows 10 application tuning
- Deploy Personal Session Desktops
- iOS RDP Client
- Android RDP Client
- Mac RDP Client
Videos
VDI Deployment using RDS
RDP on iOS and Android
Simple RDS App Publishing
RemoteFX Example
Chapter 12 – Azure IaaS and Storage
Links
- Microsoft Azure Services
- Microsoft Azure Regions
- Microsoft Azure Service Limits
- Azure Free Trial
- MSDN Azure Benefits
- Azure Classic Portal
- Azure Portal
- Azure VM Sizes
- Azure Pricing Calculator
- Hybrid Use Benefit
- Microsoft Server Software supported on Azure
- Linux Support on Azure
- Running RDS on Azure
- ClumsyLeaf CloudXplorer
- Hyrbid Failover Cluster Configuration
Scripts
Fetch Azure RDP file (AzureRDPFile.ps1)
$mySvc = "MasteringHyper-V2012R2-CS" $myVM = "Test42" Get-AzureRemoteDesktopFile -ServiceName $mySvc -Name $myVM -Launch
Commands for VM creation and management (AzureVMCreate.ps1)
Import-Module "C:Program Files (x86)Microsoft SDKsWindows AzurePowerShellAzureAzure.psd1" Get-AzurePublishSettingsFile Import-AzurePublishSettingsFile 'C:Usersadministrator.SAVILLTECHDownloadsWindows Azure MSDN - Visual Studio Ultimate-9-30-2013-credentials.publishsettings' Get-AzureSubscription Get-AzureStorageAccount Set-AzureSubscription -SubscriptionName "Windows Azure MSDN - Visual Studio Ultimate" -CurrentStorageAccount "savtechstorage" Get-AzureVMImage | ft Label,ImageName,LogicalSizeInGB Get-AzureLocation $images = Get-AzureVMImage $locations = Get-AzureLocation $mySvc = "SavillTechTest" $myPwd = "P@ssw0rd" New-AzureQuickVM -Windows -name "Sav2012VM" -ImageName $images[25].ImageName -ServiceName $mySvc -Location $locations[7].Name -AdminUserName AdminJohn -Password $myPwd #Another Example $images = Get-AzureVMImage $mySvc = "MasteringHyper-V2012R2-CS" $myAG = "MasteringHyper-V2012R2-EastUS" $myPwd = "P@ssw0rd" New-AzureQuickVM -Windows -name "Test43" -ImageName $images[46].ImageName -ServiceName $mySvc -AffinityGroup $myAG –AdminUserName AdminJohn -Password $myPwd #Adding disks $mySvc = "MasteringHyper-V2012R2-CS" $myVM = "Test43" Get-AzureVM -Name $myVM -ServiceName $mySvc | Add-AzureDataDisk -CreateNew -DiskSizeInGB 1023 -DiskLabel 'datadisk1' -LUN 0 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 1023 -DiskLabel 'datadisk2' -LUN 1 | Update-AzureVM #Moving a VHD into Azure and attaching to a VM $sourceVHD = "D:SoftwareVHDswin2k3.vhd" $destinationVHD = "https://savtechstorage.blob.core.windows.net/vhds/win2k3.vhd" Add-AzureVhd -LocalFilePath $sourceVHD -Destination $destinationVHD ` -NumberOfUploaderThreads 5 Add-AzureDisk -DiskName 'win2k3' -MediaLocation $destinationVHD ` -Label 'win2k3' -OS "Windows" #Add a disk to Azure VM $mySvc = "MasteringHyper-V2012R2-CS" $myVM = "Test42" Get-AzureVM -Name $myVM -ServiceName $mySvc | Add-AzureDataDisk -Import -DiskName vhdtst -LUN 2 | Update-AzureVM # Get VM Details for all VMs in a specific cloud Get-AzureVM -ServiceName $mySvc # Restart a VM Restart-AzureVM -ServiceName $mySvc -Name $myVM # Shutdown a VM Stop-AzureVM -ServiceName $mySvc -Name $myVM # Start a VM Start-AzureVM -ServiceName $mySvc -Name $myVM
Fetch configuration of virtual network (GetNetConfig.ps1)
Get-AzureVNetConfig | select -ExpandProperty xmlconfiguration
Initiate VPN connect (ConnectVPN.ps1)
Connect-VpnS2SInterface -Name
Configure VM with static IP in Azure fabric (SetAzureStaticIP.ps1)
Test-AzureStaticVNetIP -VNetName SavillTechVN -IPAddress 10.0.1.4 Test-AzureStaticVNetIP -VNetName SavillTechVN -IPAddress 10.0.1.10 $staticVM = Get-AzureVM -ServiceName SavillTechCS -Name staticiptest Set-AzureStaticVNetIP -VM $staticVM -IPAddress 10.0.1.10 | Update-AzureVM Get-AzureStaticVNetIP -VM $staticVM
Videos
Create Minecraft Server in Azure
Custom VM Creation with PowerShell
Azure IaaS Overview
Snapshots and Azure IaaS
Using PowerShell with Azure
Fault Domains and Availability Sets
Network Security Groups
Azure Site Recovery