Difference between revisions of "PowerCLI Powerhsell"
Michael.mast (talk | contribs) |
Michael.mast (talk | contribs) |
||
Line 75: | Line 75: | ||
</pre> | </pre> | ||
===Creating a list of machines and users=== | ===Creating a list of machines and users=== | ||
+ | ====The problem==== | ||
This is not as intuitive as other cmdlets. For example; you can run get-hvmachinesummary and get a list of machines. | This is not as intuitive as other cmdlets. For example; you can run get-hvmachinesummary and get a list of machines. | ||
+ | <pre> | ||
+ | PS C:\Windows\system32> Get-HVMachineSummary | ||
+ | Machine DesktopPool DNS Name User Host Agent Datastore Status | ||
+ | ------- ----------- -------- ---- ---- ----- --------- ------ | ||
+ | lxn-vdi-02 Test lxn-vdi-0... csp.t... 172.16.5.50 7.7.0 {vdiswa... DISCONNECTED | ||
+ | lxn-vdi-03 Test lxn-vdi-0... ad.my... 172.16.5.42 7.7.0 {vdiswa... AVAILABLE | ||
+ | lxn-vdi-04 Test lxn-vdi-0... csp.t... 172.16.5.42 7.7.0 {vdiswa... DISCONNECTED | ||
+ | csp-vdi-70 Test csp-vdi-7... ad.my... 172.16.5.42 7.4.0 {vdiswa... CONNECTED | ||
+ | </pre> | ||
+ | But then you can't select the Machine and User fields. | ||
+ | <pre> | ||
+ | PS C:\Windows\system32> Get-HVMachineSummary | select Machine,User | ||
+ | Machine User | ||
+ | ------- ---- | ||
+ | |||
+ | </pre> | ||
+ | ====The fix==== | ||
+ | Ends up things are a little different<ref>https://www.rayheffer.com/quick-guide-horizon-7-api-vmware-powercli/</ref>. Using get-member was useful to finding that there is a "base" property, then under this there was all the information I needed. | ||
+ | <pre> | ||
+ | PS C:\Windows\system32> $machines=Get-HVMachineSummary | ||
+ | PS C:\Windows\system32> $machines | get-member | ||
+ | |||
+ | |||
+ | TypeName: VMware.Hv.MachineNamesView | ||
+ | |||
+ | Name MemberType Definition | ||
+ | ---- ---------- ---------- | ||
+ | Equals Method bool Equals(System.Object obj) | ||
+ | GetHashCode Method int GetHashCode() | ||
+ | GetType Method type GetType() | ||
+ | ToString Method string ToString() | ||
+ | Base Property VMware.Hv.MachineBase Base {get;set;} | ||
+ | Id Property VMware.Hv.MachineId Id {get;set;} | ||
+ | ManagedMachineNamesData Property VMware.Hv.MachineManagedMachineNamesData ManagedMachineNamesData {get;set;} | ||
+ | MessageSecurityData Property VMware.Hv.MachineMessageSecurityData MessageSecurityData {get;set;} | ||
+ | NamesData Property VMware.Hv.MachineNamesData NamesData {get;set;} | ||
+ | |||
+ | PS C:\Windows\system32> $machines.base | ||
+ | |||
+ | |||
+ | Name : lxn-vdi-02 | ||
+ | DnsName : lxn-vdi-02.domain | ||
+ | User : VMware.Hv.UserOrGroupId | ||
+ | AccessGroup : VMware.Hv.AccessGroupId | ||
+ | Desktop : VMware.Hv.DesktopId | ||
+ | DesktopName : Test | ||
+ | Session : VMware.Hv.SessionId | ||
+ | BasicState : DISCONNECTED | ||
+ | Type : MANAGED_VIRTUAL_MACHINE | ||
+ | OperatingSystem : Windows 10 | ||
+ | OperatingSystemArchitecture : 64_bit | ||
+ | AgentVersion : 7.7.0 | ||
+ | AgentBuildNumber : 11054235 | ||
+ | RemoteExperienceAgentVersion : | ||
+ | RemoteExperienceAgentBuildNumber : 11054235 | ||
+ | |||
+ | PS C:\Windows\system32> $machines.namesdata | ||
+ | |||
+ | DesktopName UserName | ||
+ | ----------- -------- | ||
+ | Test domain.tld\user1 | ||
+ | |||
+ | </pre> | ||
+ | Then to pull it all together by creating an array<ref>http://www.get-blog.com/?p=82</ref> to hold the values. | ||
<pre> | <pre> | ||
PS C:\Windows\system32> $machines | foreach { $test=$null; $test=new-object system.object; $test | Add-Member -Type NoteProperty -Name User -Value $_.namesdata.username; Add-Member -InputObject $test -Type NoteProperty -Name Desktop -Value $_.base.name; $list+= $test} | PS C:\Windows\system32> $machines | foreach { $test=$null; $test=new-object system.object; $test | Add-Member -Type NoteProperty -Name User -Value $_.namesdata.username; Add-Member -InputObject $test -Type NoteProperty -Name Desktop -Value $_.base.name; $list+= $test} |
Revision as of 17:21, 28 March 2019
Contents
Installation
Allow powershell to run powercli cmdlets
Set-ExecutionPolicy RemoteSigned Install-Module -Name VMware.PowerCLI
Horizon
[1]It looks like vmware relies on the API to do most of the work with horizon. If you are not familiar with working with the API, like myself, this requires you to install additional scripts from github[2]. In my case I had to change the execution policy to unrestricted as the vmware.hv.helper module was not signed. Fun stuff.
Installation
After downloading the zip from github, extract and copy the modules to "C:\Program Files\WindowsPowerShell\Modules". At which point you can import the help
PS C:\Windows\system32> Connect-HVServer -server localhost ... PS C:\Windows\system32> Import-Module VMware.Hv.Helper Import-Module : Errors occurred while loading the format data file: ... The file C:\Program Files\WindowsPowerShell\Modules\VMware.Hv.Helper\VMware.HV.Helper.format.ps1xml is not digitally signed. You cannot run this script on the current system. For more information about running scripts and setting execution polic ... PS C:\Windows\system32> Set-ExecutionPolicy unrestricted ... PS C:\Windows\system32> Import-Module VMware.Hv.Helper ... PS C:\Windows\system32> Import-Module VMware.Hv.Helper PS C:\Windows\system32> get-hvhealth Id : VMware.Hv.ConnectionServerId Name : VCS-01 Status : OK Version : 7.7.0 Build : 11038474 ConnectionData : VMware.Hv.ConnectionServerHealthConnectionData DefaultCertificate : False CertificateHealth : VMware.Hv.CertificateHealthData Id : VMware.Hv.ConnectionServerId Name : VCS-02 Status : OK Version : 7.7.0 Build : 11038474 ConnectionData : VMware.Hv.ConnectionServerHealthConnectionData DefaultCertificate : False CertificateHealth : VMware.Hv.CertificateHealthData
List of Commands
PS C:\Windows\system32> Get-Command | where {$_.name -match "get-hv"} CommandType Name Version Source ----------- ---- ------- ------ Function Get-HvCommand 7.6.0.1... VMware.VimAutomation.HorizonView Function Get-HVEntitlement 1.1 VMware.Hv.Helper Function Get-HVEvent 1.1 VMware.Hv.Helper Function Get-HVEventDatabase 1.1 VMware.Hv.Helper Function Get-HVFarm 1.1 VMware.Hv.Helper Function Get-HVFarmSummary 1.1 VMware.Hv.Helper Function Get-HVGlobalEntitlement 1.1 VMware.Hv.Helper Function Get-HVGlobalSession 1.1 VMware.Hv.Helper Function Get-HVGlobalSettings 1.1 VMware.Hv.Helper Function get-hvhealth 1.1 VMware.Hv.Helper Function Get-HVHomeSite 1.1 VMware.Hv.Helper Function Get-HVInternalName 1.1 VMware.Hv.Helper Function Get-HVlicense 1.1 VMware.Hv.Helper Function get-HVlocalsession 1.1 VMware.Hv.Helper Function Get-HVMachine 1.1 VMware.Hv.Helper Function Get-HVMachineSummary 1.1 VMware.Hv.Helper Function get-hvpodfederation 1.1 VMware.Hv.Helper Function Get-HVPool 1.1 VMware.Hv.Helper Function Get-HVPoolSpec 1.1 VMware.Hv.Helper Function Get-HVPoolSummary 1.1 VMware.Hv.Helper Function Get-HVQueryFilter 1.1 VMware.Hv.Helper Function Get-HVQueryResult 1.1 VMware.Hv.Helper Function Get-HVResourceStructure 1.1 VMware.Hv.Helper Function get-hvsite 1.1 VMware.Hv.Helper
Creating a list of machines and users
The problem
This is not as intuitive as other cmdlets. For example; you can run get-hvmachinesummary and get a list of machines.
PS C:\Windows\system32> Get-HVMachineSummary Machine DesktopPool DNS Name User Host Agent Datastore Status ------- ----------- -------- ---- ---- ----- --------- ------ lxn-vdi-02 Test lxn-vdi-0... csp.t... 172.16.5.50 7.7.0 {vdiswa... DISCONNECTED lxn-vdi-03 Test lxn-vdi-0... ad.my... 172.16.5.42 7.7.0 {vdiswa... AVAILABLE lxn-vdi-04 Test lxn-vdi-0... csp.t... 172.16.5.42 7.7.0 {vdiswa... DISCONNECTED csp-vdi-70 Test csp-vdi-7... ad.my... 172.16.5.42 7.4.0 {vdiswa... CONNECTED
But then you can't select the Machine and User fields.
PS C:\Windows\system32> Get-HVMachineSummary | select Machine,User Machine User ------- ----
The fix
Ends up things are a little different[3]. Using get-member was useful to finding that there is a "base" property, then under this there was all the information I needed.
PS C:\Windows\system32> $machines=Get-HVMachineSummary PS C:\Windows\system32> $machines | get-member TypeName: VMware.Hv.MachineNamesView Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() Base Property VMware.Hv.MachineBase Base {get;set;} Id Property VMware.Hv.MachineId Id {get;set;} ManagedMachineNamesData Property VMware.Hv.MachineManagedMachineNamesData ManagedMachineNamesData {get;set;} MessageSecurityData Property VMware.Hv.MachineMessageSecurityData MessageSecurityData {get;set;} NamesData Property VMware.Hv.MachineNamesData NamesData {get;set;} PS C:\Windows\system32> $machines.base Name : lxn-vdi-02 DnsName : lxn-vdi-02.domain User : VMware.Hv.UserOrGroupId AccessGroup : VMware.Hv.AccessGroupId Desktop : VMware.Hv.DesktopId DesktopName : Test Session : VMware.Hv.SessionId BasicState : DISCONNECTED Type : MANAGED_VIRTUAL_MACHINE OperatingSystem : Windows 10 OperatingSystemArchitecture : 64_bit AgentVersion : 7.7.0 AgentBuildNumber : 11054235 RemoteExperienceAgentVersion : RemoteExperienceAgentBuildNumber : 11054235 PS C:\Windows\system32> $machines.namesdata DesktopName UserName ----------- -------- Test domain.tld\user1
Then to pull it all together by creating an array[4] to hold the values.
PS C:\Windows\system32> $machines | foreach { $test=$null; $test=new-object system.object; $test | Add-Member -Type NoteProperty -Name User -Value $_.namesdata.username; Add-Member -InputObject $test -Type NoteProperty -Name Desktop -Value $_.base.name; $list+= $test}
vcenter
Log into the server and start using commands
$cred=get-credential connect-viserver -server localhost -credential $cred get-vm
Add/Remove Hardware
CPUs
Network Interfaces
[6]The fun with this is that you can not remove a NIC from a running VM using powercli, or at least not in the way you would think. You actually need to rebuild the config with the changes you want then apply it back. Instead of doing this I decided to just disconnect the unwanted NIC and install the desired one. Thankfully this is in a DHCP environment so no modifications needed in the guest OS.
The reason for this change was due to Windows VMs losing connectivity to domain traffic using the emulated Intel NIC. According to our MS rep, we needed to change the NICs from e1000 to vmxnet3.
connect-viserver -server localhost $list=get-vm foreach ($i in $list){ $type=$i | Get-NetworkAdapter | select -ExpandProperty Type if ($type -like "e1000"){ $i | get-networkadapter -name "Network adapter 1" | set-networkadapter -connected $false -startconnected $false -confirm $false $i | new-networkadapter -networkname VDI -StartConnected -type vmxnet3} }
RAM
Lets say you created a default config with 6GB of RAM because you were an ignorant moron, and now you need to increase this to a proper 8GB.[7] The fun part is that the -MemoryGB option does not autofill, so you would be hard pressed to find this option without the Google. Gotta love Linux man pages!
Get-Folder -Name <your folder>| get-vm | where {$_.MemoryGB -eq "6.00"} | Set-VM -MemoryGB 8 -confirm:$false
Clone VM
new-vm -name <new_machine_name> -vm <source_machine_name> -vmhost <ip or host name of the physical host, not the controller>
Sample Script :
format is <scriptname>.ps1 <number of VMs to make>
ie clone_vm.ps1 3
####################################################################### ###08-14-2017 ###Specified the datastore to use because vmware is stupid, and was ###putting the VMs in the swap volume. Idiots. ####################################################################### $num1 = Read-Host -Prompt "How many VMs? " #Athenticate $cred=get-credential connect-viserver -server localhost -credential $cred #Check for enough space $neededspace=([int]$num1 * '<space needed for each VM>') $space12=(datastore -Name <datastore name> | Select-Object FreeSpaceGB | ForEach-Object { $_.FreeSpaceGB }) if ( $space12 -lt $neededspace ){ echo "Not enought space, $space12 is available and you need $neededspace" exit } #The following assumes you are creating VMs with an incrementing name based on a [a-z]+-[a-z]+-[0-9]+ format. #Get last VM created for incremental creation get-folder -name <folder name> | get-vm | select name > C:\powercli\outtest $vms=(Get-Content C:\powercli\outtest | %{"$($_.Split('-')[2])"}) $base=0 foreach($line in $vms){ if ([int]$line -gt [int]$base){ $base=$line } } $base = [int]$base + 1 $num453=0 Do{ $usehost=(Get-VMHost | Get-Random) new-vm -name vm-name-$base -vm clonefromthis -VMHost $usehost -Datastore <datastore to be used> -RunAsync -WhatIf $num453=[int]$num453 + [int]1 }until ([int]$num453 -eq [int]$num1)
Delete VM
remote-vm -vm <namme_of_vm> -deletepermanently -confirm:$false
Shutdown / Start VM
To shutdown and start VMs[8]
Get-Folder -Name pool02 | get-vm | where {$_.MemoryGB = "6.00"} | Shutdown-VM -Confirm:$false Get-Folder -Name <your folder> | get-vm | Start-VM -Confirm:$false
Snapshot Management
This will create snapshots and remove any from a month ago.
TODO:Update to remove any older than a month. Also need email notification of failed attempts
################################################# ##For creating a snapshot every week, and ##removing snapshots older than a month. ################################################# $newdate=date -Format MMddyyy $olddate=date (date).addmonths(-1) -Format MMddyyy $vsipass= echo 'password' | ConvertTo-SecureString -AsPlainText -force $cred=New-Object System.Management.Automation.PSCredential -ArgumentList username,$vsipass Connect-VIServer -server localhost -Credential $cred ##Create new snapshots Get-VM | New-Snapshot -Name "vsi-$newdate" -RunAsync -whatif ##Delete old snapshots $vsisnapshots=Get-VM | Get-Snapshot if ($vsisnapshots.Name -like "vsi-$olddate"){$_.Name | remove-Snapshot -RunAsync -whatif} Remove-Variable newdate Remove-Variable olddate exit 0 ##Check logs sleep -Seconds 3600 get-vmhost | Get-Log -Key vmkernel | select $_.Entries -ExpandProperty Entries | where {$_ -like '*Failed*snapshot*'}
- ↑ https://blogs.vmware.com/euc/2017/01/vmware-horizon-7-powercli-6-5.html
- ↑ https://github.com/vmware/PowerCLI-Example-Scripts
- ↑ https://www.rayheffer.com/quick-guide-horizon-7-api-vmware-powercli/
- ↑ http://www.get-blog.com/?p=82
- ↑ https://www.vmguru.com/2015/12/powershell-friday-adding-cpus-powercli/
- ↑ https://communities.vmware.com/message/1837346?tstart=0
- ↑ https://www.vmguru.com/2015/12/powershell-friday-adding-memory/
- ↑ https://www.vmware.com/support/developer/PowerCLI/PowerCLI41U1/html/Shutdown-VMGuest.html