Windows/Powershell/Hyper V

From r00tedvw.com wiki
(Difference between revisions)
Jump to: navigation, search
(Clone VM)
Line 46: Line 46:
 
     [parameter(ParameterSetName="createvm")][string]$AutomaticStopAction = "Shutdown",
 
     [parameter(ParameterSetName="createvm")][string]$AutomaticStopAction = "Shutdown",
 
     [parameter(ParameterSetName="createvm")][string]$Date = (Get-Date),
 
     [parameter(ParameterSetName="createvm")][string]$Date = (Get-Date),
     [parameter(ParameterSetName="createvm")][string]$Notes = "Created $Date"
+
     [parameter(ParameterSetName="createvm")][string]$Notes = "Created $Date",
 +
    [parameter(ParameterSetName="createvm")][string]$LogDir = "C:\logs"
 
)
 
)
  
 +
#Creates a new Virtual Machine
 
function CreateVM {
 
function CreateVM {
 
     New-VM -ComputerName $ComputerName `
 
     New-VM -ComputerName $ComputerName `
Line 59: Line 61:
 
}
 
}
  
 +
#Configures the new Virtual Machine
 
function ConfigureVM {
 
function ConfigureVM {
 
     Set-VM -ComputerName $ComputerName `
 
     Set-VM -ComputerName $ComputerName `
Line 72: Line 75:
 
}
 
}
  
 +
#Deletes the new Virtual Machine (only used when Configuration fails)
 
function DeleteVM {
 
function DeleteVM {
 
     $disk = Get-VMHardDiskDrive -ComputerName $ComputerName -VMName $Name | Select-Object -ExpandProperty Path
 
     $disk = Get-VMHardDiskDrive -ComputerName $ComputerName -VMName $Name | Select-Object -ExpandProperty Path
Line 78: Line 82:
 
}
 
}
  
 +
#Verify that the desired Computer Name does not already exist
 
function ValidateName {
 
function ValidateName {
 
     Get-VM -ComputerName $ComputerName | ForEach-Object {
 
     Get-VM -ComputerName $ComputerName | ForEach-Object {
Line 90: Line 95:
 
}
 
}
  
 +
#Clone the $BaseImage VHD using differencing
 
function CloneVHD {
 
function CloneVHD {
 
     #$srcVHD = -join((Split-Path -Path $NewVHDPath), "\", $BaseImage, ".vhdx")
 
     #$srcVHD = -join((Split-Path -Path $NewVHDPath), "\", $BaseImage, ".vhdx")
Line 97: Line 103:
 
}
 
}
  
 +
#Clear the Variables used
 
function ClearVariables {
 
function ClearVariables {
 
     #$Variables = Get-Variable | Where-Object {($_.Attributes -like "System.Management.Automation.ArgumentTypeConverterAttribute") -and ($_.Name -notin "ConfirmPreference","DebugPreference","ErrorActionPreference","InformationPreference","OutputEncoding","ProgressPreference","PSDefaultParameterValues","VerbosePreference","WarningPreference")} | Select-Object -ExpandProperty Name
 
     #$Variables = Get-Variable | Where-Object {($_.Attributes -like "System.Management.Automation.ArgumentTypeConverterAttribute") -and ($_.Name -notin "ConfirmPreference","DebugPreference","ErrorActionPreference","InformationPreference","OutputEncoding","ProgressPreference","PSDefaultParameterValues","VerbosePreference","WarningPreference")} | Select-Object -ExpandProperty Name
Line 105: Line 112:
 
}
 
}
  
 +
#Verify Log directory exists and create if not
 +
function VerifyLogDir {
 +
    if( -Not (Test-Path -Path $LogDir ) ) {
 +
        New-Item -ItemType directory -Path $LogDir -ErrorAction Stop
 +
    }
 +
}
  
 
#Set-PSDebug -Off
 
#Set-PSDebug -Off
Line 121: Line 134:
 
}
 
}
 
finally {
 
finally {
     echo $script:LogOut | Out-File C:\logs\vm-script.log -Append
+
     echo $script:LogOut | Out-File $LogDir\vm-script.log -Append
 
}
 
}
  
Line 136: Line 149:
 
}
 
}
 
finally {
 
finally {
     echo $script:LogOut | Out-File C:\logs\vm-script.log -Append
+
     echo $script:LogOut | Out-File $LogDir\vm-script.log -Append
 
}
 
}
  
 
#Get-Variable | ForEach-Object { $_.Name }
 
#Get-Variable | ForEach-Object { $_.Name }
 
ClearVariables</nowiki>
 
ClearVariables</nowiki>

Revision as of 16:27, 4 February 2019

Install

To Install the Hyper-V Powershell Module (Done on Windows 10 client)

PS> Get-WindowsOptionalFeature -Online -FeatureName *hyper-v* | select DisplayName, FeatureName

DisplayName                           FeatureName                            
-----------                           -----------                            
Hyper-V                               Microsoft-Hyper-V-All                  
Hyper-V Platform                      Microsoft-Hyper-V                      
Hyper-V Management Tools              Microsoft-Hyper-V-Tools-All            
Hyper-V Module for Windows PowerShell Microsoft-Hyper-V-Management-PowerShell
Hyper-V Hypervisor                    Microsoft-Hyper-V-Hypervisor           
Hyper-V Services                      Microsoft-Hyper-V-Services             
Hyper-V GUI Management Tools          Microsoft-Hyper-V-Management-Clients   



PS> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell


Path          : 
Online        : True
RestartNeeded : False


Scripts

Clone VM

Quick script to clone a VM based on an existing "master".
issues with this method will be duplication of VM values, such as hostname, sid, etc. If using an Evaluation copy of windows, when the master expires, the clones wont work anymore, so rebuilding the master every 6 months is needed.
Also, this uses VHD differencing, so the master cannot be powered on or it will break the rest of the vms created off it.

param(
    [parameter(ParameterSetName="createvm")][int64]$Epoch = [long](Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s),
    [parameter(ParameterSetName="createvm")][ValidateSet('Win2k16-Master','Win2k12r2-Master','Win2k16GVEUpgrade-Master','Win2k12r2GVEUpgrade-Master','Linux-Master')][string]$BaseImage = "Linux-Master",
    [parameter(ParameterSetName="createvm")][string]$ComputerName = "win-45mo0eqvg4g",
    [parameter(ParameterSetName="createvm")][string]$Name = -join($BaseImage, "-", $Epoch),
    [parameter(ParameterSetName="createvm")][string]$Path = "C:\ProgramData\Microsoft\Windows\Hyper-V\",
    [parameter(ParameterSetName="createvm")][string]$NewVHDPath = "C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks\$Name.vhdx",
    [parameter(ParameterSetName="createvm")][string]$NewVHDSizeBytes = 20GB,
    [parameter(ParameterSetName="createvm")][int]$Generation = 1,
    [parameter(ParameterSetName="createvm")][string]$MemoryStartupBytes = 1GB,
    [parameter(ParameterSetName="createvm")][string]$SwitchName = "External_Virtual_Switch_01",  
    [parameter(ParameterSetName="createvm")][int]$ProcessorCount = 1,
    [parameter(ParameterSetName="createvm")][int64]$MemoryMinimumBytes = 1073741824,
    [parameter(ParameterSetName="createvm")][int64]$MemoryMaximumBytes = 2147483648,
    [parameter(ParameterSetName="createvm")][string]$AutomaticStartAction = "Nothing",
    [parameter(ParameterSetName="createvm")][int]$AutomaticStartDelay = 1,
    [parameter(ParameterSetName="createvm")][string]$AutomaticStopAction = "Shutdown",
    [parameter(ParameterSetName="createvm")][string]$Date = (Get-Date),
    [parameter(ParameterSetName="createvm")][string]$Notes = "Created $Date",
    [parameter(ParameterSetName="createvm")][string]$LogDir = "C:\logs"
)

#Creates a new Virtual Machine
function CreateVM {
    New-VM -ComputerName $ComputerName `
        -Name $Name `
        -Path $Path `
        -VHDPath $newVHDPath `
        -Generation $Generation `
        -MemoryStartupBytes $MemoryStartupBytes `
        -SwitchName $SwitchName
}

#Configures the new Virtual Machine
function ConfigureVM {
    Set-VM -ComputerName $ComputerName `
        -Name $Name `
        -ProcessorCount $ProcessorCount `
        -DynamicMemory `
        -MemoryMinimumBytes $MemoryMinimumBytes `
        -MemoryMaximumBytes $MemoryMaximumBytes `
        -AutomaticStartAction $AutomaticStartAction `
        -AutomaticStartDelay $AutomaticStartDelay `
        -AutomaticStopAction $AutomaticStopAction `
        -Notes $Notes
}

#Deletes the new Virtual Machine (only used when Configuration fails)
function DeleteVM {
    $disk = Get-VMHardDiskDrive -ComputerName $ComputerName -VMName $Name | Select-Object -ExpandProperty Path
    Remove-Item $disk
    Remove-VM -ComputerName $ComputerName -Name $Name -Force
}

#Verify that the desired Computer Name does not already exist
function ValidateName {
    Get-VM -ComputerName $ComputerName | ForEach-Object {
        if ($_.VMName -eq $Name) {
            $script:LogOut = "$Date - Failed to create the VM with the name: $Name. A VM already exists with that name."
            exit
        }
        else {
            return
        }
    } 
}

#Clone the $BaseImage VHD using differencing
function CloneVHD {
    #$srcVHD = -join((Split-Path -Path $NewVHDPath), "\", $BaseImage, ".vhdx")
    $srcVHD = Get-VMHardDiskDrive -ComputerName $ComputerName -VMName $BaseImage | Select-Object -ExpandProperty Path
    $newVHD = -join((Split-Path -Path $NewVHDPath), "\", $BaseImage, "-", $Epoch, ".vhdx")
    New-VHD -Differencing -Path $newVHD -ParentPath $srcVHD
}

#Clear the Variables used
function ClearVariables {
    #$Variables = Get-Variable | Where-Object {($_.Attributes -like "System.Management.Automation.ArgumentTypeConverterAttribute") -and ($_.Name -notin "ConfirmPreference","DebugPreference","ErrorActionPreference","InformationPreference","OutputEncoding","ProgressPreference","PSDefaultParameterValues","VerbosePreference","WarningPreference")} | Select-Object -ExpandProperty Name
    $Variables = ("Epoch", "BaseImage", "ComputerName", "Name", "Path", "NewVHDPath", "NewVHDSizeBytes" , "Generation", "MemoryStartupBytes", "SwitchName", "ProcessorCount", "MemoryMinimumBytes", "MemoryMaximumBytes", "AutomaticStartAction", "AutomaticStartDelay", "AutomaticStopAction", "Date", "Notes")
    foreach ($Variable in $Variables) {
        Get-Variable $Variable | Clear-Variable -Force -ErrorAction SilentlyContinue
    }
}

#Verify Log directory exists and create if not
function VerifyLogDir {
    if( -Not (Test-Path -Path $LogDir ) ) {
        New-Item -ItemType directory -Path $LogDir -ErrorAction Stop
    }
}

#Set-PSDebug -Off
#Set-PSDebug -Trace 2

try {
    ValidateName -ErrorAction Stop
    CloneVHD -ErrorAction stop
    CreateVM -ErrorAction Stop
    $script:LogOut = "$Date - Created VM $Name"
}
catch {
    $ErrorMessage = $_.Exception.Message
    $script:LogOut = "$Date - Failed to create the VM $Name. The error message was $ErrorMessage"
    Break
}
finally {
    echo $script:LogOut | Out-File $LogDir\vm-script.log -Append
}

try {
    ConfigureVM -ErrorAction Stop
    Start-VM -ComputerName $ComputerName -Name $Name -ErrorAction Stop
    $script:LogOut = "$Date - Configured VM $Name"
}
catch {
    $ErrorMessage = $_.Exception.Message
    $script:LogOut = "$Date - Failed to configure the VM $Name. The error message was $ErrorMessage ---- Deleting VM $Name due to configuration failure."
    DeleteVM
    Break
}
finally {
    echo $script:LogOut | Out-File $LogDir\vm-script.log -Append
}

#Get-Variable | ForEach-Object { $_.Name }
ClearVariables
Personal tools
Namespaces

Variants
Actions
Navigation
Mediawiki
Confluence
DevOps Tools
Open Source Products
Ubuntu
Ubuntu 22
Mac OSX
Oracle Linux
AWS
Windows
OpenVPN
Grafana
InfluxDB2
TrueNas
MagicMirror
OwnCloud
Pivotal
osTicket
OTRS
phpBB
WordPress
VmWare ESXI 5.1
Crypto currencies
HTML
CSS
Python
Java Script
PHP
Raspberry Pi
Canvas LMS
Kaltura Media Server
Plex Media Server
MetaSploit
Zoneminder
ShinobiCE
Photoshop CS2
Fortinet
Uploaded
Certifications
General Info
Games
Meal Plans
NC Statutes
2020 Election
Volkswagen
Covid
NCDMV
Toolbox