A couple of weeks ago Charu Chaubal published his draft vSphere 4.0 Security Hardening Guides in the Security & vShield Zones community. If you haven’t read them yet, you definitely have to put them on your To-do list.
A vSphere administrator often considers security as a necessary evil that he has to take care of at a point in time, preferably a few days before an audit is going to take place 😉
Charu’s Guides can make this exercise a lot easier. And if we add to those guides some scripts to automate the hardening process, the vSphere administrator has no more excuses to tackle security on a regular basis (like it should be !).
Background information
Charu’s Guides are by far not the only security resources that are available to the vSphere administrator, but at this point in time they are in any case the most-up-to-date resources.
The security bible is of course Edward Haletky‘s book VMware vSphere and Virtual Infrastructure Security. A book every serious vSphere administrator should have on his bookshelf.
Some other noteworthy resources to consult:
Automating the hardening process
The first to publish an automated process based on Charu’s Hardening Guides was William Lam. His vmwarevSphereSecurityHardeningReportCheck.pl script produces a great report, where you can see immediately which hardening guidelines need your attention.
My idea was to automate not only the verification but also the correction, where possible.
Purely random, I have chosen the Virtual Machine Hardening Guide as my first attempt on automating the hardening process.
Preparing the script
If you read the Virtual Machine Guide you will notice that most of the guidelines are composed of conditions that can be easily automated.
My first challenge was to find a “structure” to store the guidelines. After some testing I came up with this structure.
Each recommendation is represented by such an object. And each of these objects is stored in a hash table with the vulnerability code as the key.
In these objects the following properties are present:
- Level: indicates for which operational environment the recommendation is intended
- Combination: a recommendation can have multiple components. This property indicates how they shall be combined
- Keys: the parameters to check for. Is an array
- Operation: an array with the operation to perform on the Key-Value combination
- Values: the actual values the parameters are checked against
An example will hopefully make this a bit clearer. Let’s take recommendation VMX01.
This recommendation tells you to check two parameters (“isolation.tools.diskWiper.disable” and “isolation.tools.diskShrink.disable“) in the VMX file. Both parameters should have the value “TRUE”. This gives the following object, which is added to the hash table with the key “VMX01”.
The second problem to solve was the multitude of operators that are used in the recommendations. These range from “equal” over “not equal” to “exists” and “not present”, and some more. Thanks to PowerShell this was in the end not too difficult to solve. More on these operators later on in the script annotations.
The script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# Hardening: Virtual Machines # Constants $VmMax = @{} $VmMax["floppy"] = 2 $VmMax["serial"] = 4 $VmMax["parallel"] = 3 $VmMax["ide"] = 2,2 $VmMax["ethernet"] = 10 $VMThreats = @{} $VMThreats["VMX01"] = New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("isolation.tools.diskWiper.disable", "isolation.tools.diskShrink.disable") Operation = @("eq", "eq") Values = @("TRUE","TRUE") } $VMThreats["VMX02"] = New-Object PSObject -Property @{ Level = "DMZ" Combination = "and" Keys = @("remoteDisplay.maxConnections") Operation = @("eq") Values = @(1) } $VMThreats["VMX03"] = New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("isolation.tools.copy.disable", "isolation.tools.paste.disable", "isolation.tools.setGUIOptions.disable") Operation = @("eq", "eq", "eq") Values = @("TRUE", "TRUE", "TRUE") } $VMThreats["VMX10"] = New-Object PSObject -Property @{ Level = "Enterprise" Combination = "or" Keys = @("floppyX.present", "serialX.present", "parallelX.present", "usb.present", "ideX:Y.present") Operation = @("not_present", "not_present", "not_present", "not_present", "not_present") Values = New-Object string[] 5 } $VMThreats["VMX11"] = New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("isolation.device.connectable.disable", "isolation.device.edit.disable") Operation = @("eq", "eq") Values = @("TRUE", "TRUE") } $VMThreats["VMX12"] = New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("vmci0.unrestricted") Operation = @("eq") Values = @("FALSE") } $VMThreats["VMX20"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("log.rotatesize", "log.keepold") Operation = @("le","le") Values = @(1000000, 10)}), (New-Object PSObject -Property @{ Level = "SSLF" Combination = "and" Keys = @("isolation.tools.log.disable") Operation = @("eq") Values = @("TRUE") }) $VMThreats["VMX21"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("tools.setInfo.sizeLimit") Operation = @("le") Values = @(1048576)}), (New-Object PSObject -Property @{ Level = "SSLF" Combination = "and" Keys = @("isolation.tools.setInfo.disable") Operation = @("eq") Values = @("TRUE") }) # $VMThreats["VMX22"] = $null $VMThreats["VMX30"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("guest.command.enabled") Operation = @("eq") Values = @("FALSE")}) $VMThreats["VMX31"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("tools.guestlib.enableHostInfo") Operation = @("eq") Values = @("FALSE")}) $VMThreats["VMX50"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("vmsafe.enable", "host_portgroup_vmsafe") Operation = @("ne", "not_exist") Values = @("TRUE", (New-Object string[] 5))}) $VMThreats["VMX51"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("vmsafe.enable", "ethernetX.networkName") Operation = @("ne", "ne") Values = @("TRUE", "vmsafe-appliances")}) $VMThreats["VMX52"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("vmsafe.enable", "vmsafe.agentAddress", "vmsafe.agentPort") Operation = @("ne", "not_present", "not_present") Values = @("TRUE", "", "")}) $VMThreats["VMX53"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("vmsafe.enable", "host_dvswitch_dvfilter") Operation = @("ne", "not_exist") Values = @("TRUE", "")}) $VMThreats["VMX54"] = (New-Object PSObject -Property @{ Level = "Enterprise" Combination = "and" Keys = @("vmsafe.enable", "ethernetX.networkName") Operation = @("ne", "not_present") Values = @("TRUE", "")}) # $VMThreats["VMX55"] = (New-Object PSObject -Property @{ # Level = "Enterprise" # Combination = "and" # Keys = @("vmsafe.enable", # "ethernetX.filterZ.name") # Operation = @("ne", # "not_present") # Values = @("TRUE", # "")}) # Utility functions function Set-VMXOption{ param($key, $value) $option = New-Object VMware.Vim.optionvalue $option.Key = $key $option.Value = $value $option } function Test-VmxDevPresence{ param($devSpec, $case) if($devSpec.Contains("X")){ $devType = $devSpec.Split("X")[0] $devProperty = $devSpec.Split("X")[1] $devProperty = $devProperty.Split("Y") if($case -eq "not_present"){ $result = $true } else{ $result = $false } if($devProperty.Count -ne 1){ $maxX = ($VmMax[$devType])[0] $maxY = ($VmMax[$devType])[1] } else{ $maxX = $VmMax[$devType] } for($j=0; $j -lt $maxX; $j++){ if($devProperty.Count -ne 1){ for($k=0; $k -lt $maxY; $k++){ if($case -eq "not_present"){ $result = $result -or $VMXtab[$devType + $j + $devProperty[0] + $k + $devProperty[1]] -ne $null } else{ $result = $result -or $VMXtab[$devType + $j + $devProperty[0] + $k + $devProperty[1]] -eq $null } } } else{ if($case -eq "not_present"){ $result = $result -and $VMXtab[$devType + $j + $devProperty] -eq $null } else{ $result = $result -or $VMXtab[$devType + $j + $devProperty] -ne $null } } } } else{ $devType = $devSpec.Split(".")[0] if($case -eq "not_present"){ $result = $result -or $VMXtab[$devSpec] -ne $null } else{ $result = $result -or $VMXtab[$devSpec] -eq $null } } $result } function Test-PortGroup{ param($pgName, $esx) if(($esx.Config.Network.Portgroup | where {$_.Spec.Name -eq $pgName})){$true}else{$false} } function Test-dvSwitch{ param($dvSwName,$esx) if(($esx.Config.Network.ProxySwitch | where {$_.DvsName -eq $dvSwName})){$true}else{$false} } function Test-HostEntityExist{ param($entSpec, $entValue, $vmObj) $specArray = $entSpec.Split("_") switch($specArray[0]){ "host"{ switch($specArray[1]){ "portgroup"{ $result = Test-Portgroup $specArray[2] (Get-View $vm.Runtime.Host) } "dvswitch"{ $result = Test-dvSwitch $specArray[2] (Get-View $vm.Runtime.Host) } } } Default{ $entSpec } } $result } # Script settings $report = $true $correct = $false $scope = "Enterprise" $reportArray = @() # Collect objects to be verified and/or corrected $rootNode = Get-Folder -Name "VMXtest" | Get-View $vms = Get-View -ViewType VirtualMachine -SearchRoot $rootNode.MoRef # Loop through all collected objects foreach($vm in $vms){ # Init # Create VirtualMachineConfigSpec (if corrections were requested) if($correct){ $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec } # Load VMX values in hash table $VMXtab = @{} $vm.Config.ExtraConfig | % { $VMXtab[$_.Key] = $_.Value } # Check all hardening codes $VMThreats.GetEnumerator() | Sort-Object -Property "Name" | % { $protected = $true if($_.Value.Combination -eq "or"){ $protected = $false } foreach($ThreatParam in $_.Value){ if($ThreatParam.Level -eq $scope -or $scope -eq "All"){ for($i = 0; $i -lt $ThreatParam.Keys.Count; $i++){ switch($ThreatParam.Operation[$i]){ "eq"{ $result = $VMXtab[$ThreatParam.Keys[$i]] -eq $ThreatParam.Values[$i] } "ne"{ $result = $VMXtab[$ThreatParam.Keys[$i]] -ne $ThreatParam.Values[$i] } "le"{ $result = $VMXtab[$ThreatParam.Keys[$i]] -le $ThreatParam.Values[$i] } "not_present"{ $result = Test-VmxDevPresence $ThreatParam.Keys[$i] $_ } "present"{ $result = Test-VmxDevPresence $ThreatParam.Keys[$i] $_ } "not_exist"{ $result = !(Test-HostEntityExist $ThreatParam.Keys[$i] $ThreatParam.Values[$i] $vm) } Default{ $ThreatParam } } switch($_.Value.Combination){ "and"{ $protected = $protected -and $result } "or"{ $protected = $protected -or $result } } if($report){ $reportArray += New-Object PSObject -Property @{ VMName = $vm.Name Code = $_.Key Level = $ThreatParam.Level Condition = $ThreatParam.Keys[$i] Value = $VMXtab[$ThreatParam.Keys[$i]] Desired = $ThreatParam.Values[$i] OperDesired = $ThreatParam.Operation[$i] Protected = $protected } } if($correct){ $vmConfigSpec.extraconfig += (Set-VMXOption $ThreatParam.Keys[$i] $ThreatParam.Values[$i]) } } } } } # Final: reconfigure the VM (if corrections were requested) if($correct){ $vm.ReconfigVM($vmConfigSpec) } } if($report){ $reportArray | Sort-Object -Property Code,VMName | Export-Csv "C:\Sec-Hard-VM-risks.csv" -NoTypeInformation -UseCulture } |
Annotations
Line 4-9: This hash table contains the maxima, as described in Configuration Maximums, for specific virtual hardware.
Line 11: This is the hash table that will hold all recommendations. The key for each recommendation object is the Code from the Hardening Guide.
Line 12-161: All the recommendations that I was able to encode as an object.
Line 162-170: I’m not sure at this point in time if recommendation VMX55 can be automated. I couldn’t find any definition of the VMX parameter “ethernetX.filterY.name”. I don’t know how many “filters” there can be. I left this recomendation out for now.
Line 173-180: Function to create a new VMX parameter if the script is run with the option to implement the recommendations.
Line 182-233: The Test-VMXDevPresence function check if specific devices are present in the VMX file.
Line 185: Some devices can be present more than once. That’s were the capital X is used for. Together with maximums in hash table $VmMax this allows the script to test all possible parameters for a specific device type.
Line 188: IDE devices have two numerical fields in their parameters. That’s why the capital Y appears in the condition for IDE devices.
Line 206, 209, 215, 218, 226, 229: Once the parameter is composed it’s rather straightforward to look up if the parameter exists by using the hash table $VMXtab.
Line 235-239: Function to test if there exists a portgroup with the name in $pgName on the ESX server that hosts the specific virtual machine.
Line 241-245: Function to test if there exists a dvSwitch with the name in $dvSwName on the ESX server that hosts the specific virtual machine.
Line 247-267: Driving function that checks if an object with a specific name exists on the ESX server that hosts the specific virtual machine.
Line 270: The Boolean variable $report defines if the script should produce a report.
Line 271: The Boolean variable $correct defines if the script should apply the recommendations
Line 272: The string variable $scope specifies to the script which recommendations should be investigated. Possible values are “Enterprise”, “DMZ”, “SSLF” or “All”.
Line 277-278: These lines select the virtual machines that will be checked and eventually hardened. These lines can be replaced by any other selection mechanism, as long as the $vms variable is populated by one or more VirtualMachine objects.
Line 289-292: These lines load all VMX parameters into a hash table. The key is the parameter name.
Line 295: This loop runs through all recommendations.
Line 303-325: This switch construction handles all Operation types.
Line 326-333: This switch construction handles all Combination options.
Line 346-348: If the corrective action was requested (the $correct variable) then all the parameter changes are added to the extraconfig property.
Line 355-357: When all recommendations are verified and when the corrective action was requested, this call to ReconfigVm will apply all changes required by the recommendations.
The report
If the reporting option is selected the script will produce a CSV file that shows what was found on each virtual machine for each of the recommendations.
In the report you see the following columns.
- Code: The recommendation code.
- Level: The recommendation level which was used.
- Condition: The “keys” from the recommendation object above
- Value: The value for the key that was found on the virtual machine
- Desired: The value that is recommended
- OperDesired: How the conditions for a specific recommendation were combined. The Combination property in the recommendation object.
- Protected: Indicates if the virtual machine is protected against the vulnerability described in the recommendation
Conclusion
As I already mentioned above not all recommendations are implemented in this version of the script.
- VMX55 uses the ethernetX.filterY.name parameter but for now I don’t know the syntax and limits of this parameter
- The removal of a portgroup and a dvSwitch as recommended in VMX50 and VMX53 is not implemented in the script as I feel this should belong in the Host Hardening Guide
- VMX03 only mentions isolation.tools.copy.disable and isolation.tools.paste.disable but apparently there are also the parameters isolation.tools.copy.enable and isolation.tools.paste.enable. I think they should be included in the recommendation as well. And it would be useful to know which of these takes precedence.
And as this is the first version of this script there will most probably be some “features” present in the script. I tested against a number of configurations but with the abundance of VMX parameters, it is nearly impossible to have a test scenario that includes all possible combinations.
If you encounter a bug or a problem please forward me the VMX file that caused the problem. And if you have any suggestions, feel free to forward them to me as well.
To close, a word of warning, before you use this to implement the recommendations in your production environment test, test and test again. And make sure you have a fall-back scenario if something goes wrong !
RobG
Hi Luc,
Been using this script for a long time but now vSphere 5 is out i’d like to use it still, should this script work with vSphere 5 ?? as in ESXi 5 VM’s.
Dave
Luc,
In the script, guest.command.enabled is tested in VMX30. VMware has a KB article 1010103
seems to indicate the parameter name is guest.commands.enabled (with an ‘s’). Should the script be updated to guest.commands.enabled or are these two different parms?
Thank you,
Dave
piet200
Luc,
VMX10 doesn’t work for me. All other changes work fine but VMX10.
The error I get is:
Exception calling “ReconfigVM” with “1” argument(s): “A specified parameter was not correct.
”
At C:\4.VMhardening.ps1:302 char:17
+ $vm.ReconfigVM <<<< ($vmConfigSpec)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any idea ?
Rob
I used this script last year, and didn’t have a problem. I’ve built some new ESXi4.1 hosts, standalone not connected to vCenter, and am trying to run the script. I get the following message when I set (line 271) $correct = $true:
Exception calling “ReconfigVM” with “1” argument(s): “fault.RestrictedVersion.summary”
At C:\scripts\ESXi_hardening\report-harding-vm-guests.ps1:357 char:19
+ $vm.ReconfigVM <<<< ($vmConfigSpec)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
The only other change I made was on line 278: $rootNode = Get-VM | Get-View
LucD
@Rob, it looks as if you are using a “free” ESXi installation (indicated by the restrictedversion fault).
I’m afraid you only have read-only access to that type of server, no changes allowed.
Serge Meeuwsen
Hi Luc,
Great script, I really like the way you set it up, it’s easily extensible.
I have one issue tho I’m trying to figure out and hoping you have some ideas.
Somehow in my lab environment, the $vm.config.extraconfig doesn’t contain all keys and values present in the VMX file. For instance I have a VM which does have floppy0.present = “TRUE” in its VMX file, but when I examine that VM’s .config.extra.config, it’s not present there.
Hence the script cannot report correctly in this case.
My Lab environment is as follows:
ESXi 4.1.0 build 348841
vCenter is version 4.1.0 345043
PowerCLI version is 4.1 U1 build 332441
Thanks!
LucD
@Serge, you are correct, the floppy drive presence is not visible in the ExtraConfig property in vSphere 4.x.
It seems that we will have to use the Config.Hardware.Device table to determine if there is a connected virtual floppy present.
This will require some fundamental re-writing of the script, I’m afraid.
PJT
Hi LucD,
Great script! I’ve looking for something to audit these isolation settings to ensure they are always applied or changed. Do you know of other scripts or other tools for that purpose?
Thanks,
LucD
@PJT, thanks.
There will a chapter in our upcoming book on hardening.
There are some commercial tools on the market that do a security check of your environment.
Abe
@LucD
Disclaimer: That would only work if you were not using vmsafe.
Also, I noticed that if you run the script with both the $report and $correct set to $true then the report wasn’t updated with the configurations that were changed.
Abe
@LucD
Here’s an example of how I correct it for VMX50:
$VMThreats[“VMX51”] = (New-Object PSObject -Property @{
Level = “Enterprise”
Combination = “and”
Keys = @(“vmsafe.enable”,
“ethernetX.networkName”)
Operation = @(“eq”,
“eq”)
Values = @(“FALSE”,
“”)})
LucD
@Abe, that’s indeed a good solution.
Thanks for sharing that.
Abe
I found that the settings that had an operation of “ne” (as “vmsafe.enable” shown on lines 114-161) actually set the value to what was defined in “Values” when you ran the script with $correct = $true. I think this is due to the line:
“$vmConfigSpec.extraconfig += (Set-VMXOption $ThreatParam.Keys[$i] $ThreatParam.Values[$i])”
It does not have a parameter in the case that the operation is set to “ne”. I loved the script and it worked great otherwise.
LucD
@Abe, you’re absolutely right.
I’ll have to figure out how to correct these “ne” conditions in the script.
I guess an “ne” requirement can be translated in an “eq” requirement. But that would mean the script needs to know all the possible values.
Another alternative is to remove the key from the .VMX file. But that means I would need to make sure that the default are not conflicting with the requirement.
I definitely have to do a bit of brainstorming on this one 🙂
Rahul
Hi Luc… the script is awsome bt I am getting the following msg when running it.
************************************************
Index operation failed; the array index evaluated to null.
At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\My-Scripts\Testing\Scan_VMX.ps1:291 char:11
+ $VMXtab[ <<<< $_.Key] = $_.Value
+ CategoryInfo : InvalidOperation: (System.Collections.Hashtable:Hashtable) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
************************************************
LucD
@Rahul, thanks.
It looks as if you have 1 or more guests with an empty VMX file.
Can you execute the following line and check if there are any guests that have 0 (zero) in the Count column ?
PowerCLI 4.1 version
Get-VM | Select Name,@{N="Count";E={$_.Extensiondata.Config.ExtraConfig.Count}} | ft -AutoSize
pre-PowerCLI 4.1 version
Get-View -ViewType VirtualMachine | Select Name,@{N="Count";E={$_.Config.ExtraConfig.Count}} | ft -AutoSize
Iben Rodriguez
Great work both of you. Not sure why I am only just now finding this site but better late than never.
There’s a new version of the hardening guide out since April and there are some updates needed still.
Keep the feedback coming so we can improve it.
As for the disk shrink issue – this is not even supported with VMware ESX so not sure why we recommend this setting. But we will improve as we go along.
Skywalker
Luc,
If I just want to get the values of “isolation.tools.setInfo.disable” and ” and “isolation.tools.paste.disable” for each VM. Could you help simplify the script? Thanks.
elad
very good script –> right on
LucD
Thanks. I hope to post scripts for the other hardening parts in the near future.
Doug
Excellent script. Not something thrown together, but planned out and well executed — as I would expect from the great LucD. Bravo and thank you for your efforts! :
Doug
LucD
Thanks Doug
Ken
it works now, i did not even have a profile.ps1 so i created it.
i might recommend to group the output by vm instead. i can solve this for myself by adding a sort to the VMName column.
thanks for this tool.
LucD
Ken,you only have to change the order of the names on the Sort-Object -Property parameter in line 360.
Ken
I’m also very inexperienced with powershell. I upgraded to v2 RTM and receive these errors:
The term ‘Get-Folder’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At D:\hardesx.ps1:277 char:23
+ $rootNode = Get-Folder <<<< -Name "VMXtest" | Get-View
+ CategoryInfo : ObjectNotFound: (Get-Folder:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I did a bit of reading to try and narrow the problem down and made sure RemoteScripts was enabled and checked that the path was correct.
LucD
Hi Ken, it looks as if the PowerCLI snapin is not loaded when you execute the script.
You can try adding the following line to the top of the script:
Add-PsSnapin VMware.VimAutomation.Core
I don’t know how you start the script (PowerCLI prompt, PowerShell prompt or one of the GUIs) but ultimately it would be better to add the line above to one the profile.ps1 files.
See Tobias’s paragraph called Profile: Autostart Scripts for more information.
J. Kalf
Luc,
Very nice script. I’ve given it a test run. But I can’t seem to get it working right at the moment. I’m no vPowercli specialist, so that might be the issue at hand.
But on running the script I get the following error message over and over again:
—
New-Object : A parameter cannot be found that matches parameter name ‘Property’
—
I’m running powershell 1.(latest) with vPowercli 4.0.1-208462
Jelle
LucD
Hi Jelle,
That’s an oversight from me, I should have mentioned that the script requires PowerShell v2 RTM.
The -Property parameter on the New-Object cmdlet is new in PS v2 RTM.
Sorry about that,
Luc.
John Reeman
Really good script, well done. I am one of the developers behind a tool called vminformer, it does what your script does and more in terms of showing you graphically where your issues are.
Interesting you mention the isolation.tools.copy.enable and isolation.tools.paste.enable as there is also isolation.device.edit.disable which seems to be similar to isolation.tools.connectable.disable and again not sure which one takes precedence.
Don’t want this to sound like a sales plug but would appreciate some feedback, so if you do get a chance to take a look send me an email and let me know your thoughts.
Cheers
John
LucD
Hi John,
Thanks.
Had a quick look at your site and the product looks very interesting. Just requested for a download of the Community Edition. I will definitely give it a spin and send you my impressions.
Luc.
PS: I liked the your Scoobydoo movie on YouTube. It’s a very good vSphere security risks overview.