Академический Документы
Профессиональный Документы
Культура Документы
INTRODUCTION ........................................................................................................................ 5
Requirements .................................................................................................................. 10
Before Installation........................................................................................................... 11
Object State.................................................................................................................21
2
Retrieve Basic Data on vSphere Objects ...................................................................... 23
List Virtual Machines and the Hosts They are Running on ..............................................24
PSScriptAnalyzer ............................................................................................................. 34
Functions .......................................................................................................................... 34
Preparation .................................................................................................................40
HTML Reporting............................................................................................................... 46
3
CHAPTER 6. USE CASES ........................................................................................................ 50
Requirements ..............................................................................................................50
Script Explained...........................................................................................................51
Help() ..........................................................................................................................71
Invoke() .......................................................................................................................72
CreateArgs().................................................................................................................72
4
INTRODUCTION
Scripting and PowerCLI are words that most people working with VMware products
know pretty well and have used once or twice. Everyone knows that scripting and
automation are great assests to have in your toolbox. The problem usually is that
getting into scripting appears daunting to many people who feel like the learning
curve is just too steep, and they usually don't know where to start. The good thing
is you don't need to learn everything straight away to start working with PowerShell
and PowerCLI. Once you have the basics down and have your curiosity tickled,
you’ll learn what you need as you go, a lot faster than you thought you would!
This eBook doesn't contain everything, but it contains what you need to know to get
started. Just like a mechanic’s starter kit, you can't build a car engine with it, but you
can do the basics to call yourself a mechanic. This eBook contains the first few steps
of a long stairway paved with cmdlets, properties, and methods and few more treats
along the way. We’ll start by covering the basics, then we’ll break the examples into
sections about completing specific tasks so you can get an idea of where certain
5
CHAPTER 1. ABOUT POWERCLI
Let's get to know PowerCLI a little better before we start getting our hands dirty
in the command prompt. If you are reading this you probably already know what
PowerCLI is about or have a vague idea of it, but it’s fine you don’t. After a while
working with it, it becomes second nature, and you won't be able to imagine life
integration with all of their components has significantly improved over the years,
WHAT IS PowerCLI?
Contrary to what many believe, PowerCLI is not in fact a stand-alone software but
rather a command-line and scripting tool built on Windows PowerShell for managing
launch PowerShell and load the PowerCLI snap-ins in the session. This behavior
changed back in version 6.5.1 when the executable file was removed and replaced
by a suite of PowerShell modules to install from within the prompt itself. This new
deployment method is preferred because these modules are now part of Microsoft’s
6
These modules provide the means to interact with the components of a VMware
environment and offer more than 600 cmdlets! The below command returns a full list
of VMware-Associated Cmdlets!
addition to anyone's resume, there are many compelling reasons why one should
Virtualization is generally associated with cool words like system architecture, design,
and troubleshooting of complex environments. While this is true, the operational side
of it is often forgotten because it is a lot less attractive and can consist of monotonous
7
Luckily, it’s possible to avoid a lot of this manual labour while still ensuring these
important but boring tasks are taken care of. PowerCLI allows you to automate many
of these tasks, be it in the command prompt or a script, and they can be addressed
as a scheduled task. People are often surprised when they see the time they could
save and then begin to use PowerCLI to do more interesting things (like writing
When something goes wrong, 9 times out of 10, it is due to human error. For example,
you will never be free from the possibility of a hardware component failing or a bug
in firmware, as these are events you cannot prevent. What PowerCLI can help you
with is consistency and avoiding silly mistakes. What if you detached the wrong
storage LUN in the vSphere client because you read "b" instead of "d" and 15 VMs
go down? The VMs wouldn't have gone down if you gathered the LUN ID from
port group with VLAN ID 148 instead of 1048 and subsequently a VM fails to recover
all port-groups were created the same way from the start.
monitoring system like Zabbix or Nagios and enable vCenter alerts at the very least.
Complementary solutions like vRealize Operations Manager can greatly improve your
visibility of the environment, but as great as they are, these come at a cost and may
8
Once again, PowerCLI can increase your reporting and alerting capabilities to fill
the gaps in your monitoring. You can create well-formatted HTML reports using
PowerCLI and have them served on a web page or even sent automatically at set
and then some. You can generally get the information you are after (however
specific), or change a configuration much more quickly than in the vSphere client.
number of VMs, which we will talk about more extensively later on in this book.
9
CHAPTER 2. INSTALLING POWERCLI
REQUIREMENTS
All the requirements and interoperability information about PowerCLI is in the VMware
compatibility matrix. If you have any concerns about PowerCLI working with a given
product version, head over to VMware code, select your version of PowerCLI and open
You will need .NET Framework 4.5 and above. Since version 11.2.0, PowerCLI is
to PowerShell Core.
10
BEFORE INSTALLATION
Before installing the latest version, you need to uninstall any version of PowerCLI
older than 6.5 R1 from your system. You can uninstall it like any installed software
INSTALLATION
The installation procedure has been simplified since the modules have been added
The modules will be automatically downloaded and stored in the correct folder.
Note that you can use the -Scope parameter to make the PowerCLI modules
available to AllUsers.
11
UPDATE
the Update-Module cmdlet to update PowerCLI as it does not remove any files
• Then install the new one by following the install procedure described
previously
INSTALLATION
If your system does not have internet access, you must download PowerCLI as a zip
file from the VMware website and copy the modules into your modules folder. Unlike
many of the VMware products, you don't need to be logged in to download PowerCLI.
• Head over to VMware code and select the latest version of PowerCLI
12
• Transfer the file to your offline machine and copy all the folders present
in the zip to your PowerShell Modules folder. Again, choose the location
UPDATE
To update PowerCLI, delete the existing PowerCLI module folders and follow
EXECUTION POLICY
Execution policies are a security mechanism that determines if files are allowed
to load in PowerShell such as config files, modules, scripts, etc. You can find your
Get-ExecutionPolicy
You may need to change the default execution policy to be able to run scripts you
have written. Unless a Group Policy Object changed the default setting, you don't
need to change this if you are using a Windows Server Operating System. However,
it is required for Windows client Operating Systems (i.e., Windows 10) as the default
13
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
Highly secured environments may require all scripts (even those written in-house)
to be digitally signed by an enterprise PKI. Meaning that the execution policy must
be set to AllSigned if not already done via Group Policy. In which case you must
14
CHAPTER 3. GETTING STARTED
WITH PowerCLI
CONFIGURE PowerCLI
Apart from the execution policy mentioned previously, there is no further
a few settings that could be useful. You can use the Set-PowerCLIConfiguration
Once again, a "-scope" parameter allows you to modify the settings for the session,
current user, or all users. The Session scope has the highest priority, and the All Users
Note: Setting configured with the Session scope will NOT persist after
Other parameters allow you to configure settings such as whether or not to use
the system proxy, display warnings about deprecated elements, increase the timeout
of commands (which defaults at 5 minutes). You can find all the parameters with
Let’s take a look at two of the most common parameters you’ll use here.
15
-DefaultVIServerMode
your environment contains more than one vCenter server. This parameter defines
whether you can connect to more than one vCenter at a time. It is important
because a mistake can quickly happen if you have forgotten that you have two active
vCenter sessions in your PowerShell prompt, for example. You typically won’t have
problems with Get commands where you’re just retrieving information, but you
REALLY need to start paying attention once you start working with Set,
Set-PowerCLIConfiguration -DefaultVIServerMode
Restrict to one vCenter
Single
Set-PowerCLIConfiguration -DefaultVIServerMode
Allow multiple vCenter
Multiple
-InvalidCertificateAction
This parameter defines the behavior of the Connect-VIServer with regards to the vCenter
certificate. This parameter does not apply to you if the installed vCenter certificate
is signed by a trusted root CA. If the certificate isn’t valid (expired, self-signed, not
trusted, etc), the default setting is to display a warning when you establish the
connection. You can change this behavior using the following parameter.
16
Prompt before continuing. Possible choices
Set-PowerCLIConfiguration –
are Deny, Accept for once,
InvalidCertificateAction Prompt
Accept permanently, Accept for all users.
Set-PowerCLIConfiguration –
No connection established
InvalidCertificateAction Fail
CONNECT TO VCENTER
You can connect to an ESXi host or vCenter instances with the Connect-VIServer
cmdlet. You can do it a few different ways thanks to the various parameters it offers.
You can connect with a Session ID, a credential object, a user password/combination,
The most common way to connect is to specify the IP or FQDN of the server and use
the current PowerShell session user if it has permissions on the vCenter server.
Connect-VIServer vcsa.test.local
You can get the list of the connected vCenter servers by displaying the content
a successful connection. A tiny caveat here: this is a variable. This means that
17
if a network interruption occurs, for instance, and the session is no longer connected,
the variable remains populated, and in which case you will need to reconnect, causing
the variable to be overwritten with the new active session. This object contains
information about the server and the session, such as the session ID, user, version,
and build… If it cannot connect with the current user, a credential popup appears to
let you type a different user/password combination. You can also add the credential
parameter, so you don’t have to wait for the current user to fail the connection.
I would also like to point out a nifty little parameter of this cmdlet that displays
a list of the recently connected vCenter servers. You don’t see this one too often,
but it is very useful if you manage a bunch of different servers. You can then select
Connect-VIServer -menu
CREDENTIAL STORE
By default, when connecting to a vCenter server, PowerCLI checks what is
the Credential Store saves sets of host credentials to have at your disposal.
18
1. Credentials are encrypted and stored securely (don’t put credentials
in your scripts!).
To use the credential store, you need to save credentials into it, as shown below.
-Password "Don'tL00kAtM3!"
Once credentials are stored, you can connect to vCenter with the usual command,
as discussed earlier.
Connect-VIServer srv-vcenter.domain.pri
PowerCLI OBJECTS
Just like with traditional PowerShell, you will constantly be working with PowerShell
objects. Any object acquired with a PowerCLI cmdlet will be assigned the specific type
You’ll discover them as you go and as you get deeper into PowerCLI.
19
OBJECT-BY-NAME SELECTION (OBN)
PowerCLI includes this mechanism called OBN selection that allows you to refer
to an object by its name instead of passing the actual object through the pipeline
in the prompt. OBN selection also supports wildcards and multiple arguments.
• Traditional Selection
• OBN Selection
DATA STRUCTURE
Data structure is not something you will worry about when working with PowerCLI.
on behind the scenes. For that reason, we won't go too deep into the theory and will
There are four categories types for objects in PowerCLI, and each serves a different
purpose.
20
1. Managed Object Types — Makes managing objects possible.
They can contain both properties and methods, meaning they can hold
values (VM name, Data objects) or run an action (Start VM). A managed
2. Data Object Types — As the name suggests, they hold data about the object.
They can contain the MoRef (which allows you to get a managed object)
3. Enumerated Object Types — Data Objects that can only store values
or objects from a pre-defined set and nothing else. They are usually used
for runtime status like the power state of a virtual machine that can
OBJECT STATE
running the cmdlet every time to retrieve it. It saves time as a variable name is usually
shorter to type than a cmdlet, and there is no processing time because it is already
stored locally. When doing so, you are storing its state at this point in time.
Meaning that if a property were to change on the server-side object, it would not
be reflected on the object in the variable. You would then need to run the cmdlet
21
EXAMPLE WITH VMOTION
VMHost
------
ESX-Host-1
As you can see it is still showing the host, it was previously running on.
VMHost
------
ESX-Host-1
5. Update the variable and display the host value once again:
The variable now reflects the actual value of the server-side object.
VMHost
------
ESX-Host-2
22
You can see how this could cause confusion on systems managed by several
administrators, with reporting scripts showing outdated data about the environment,
for example.
Note: this is true for all kind of objects, not only virtual machines.
with PowerCLI (especially if you are fairly new to PowerShell as well). If you don’t have a
test lab to practice with I recommend being on the safe side and stick with
Get commands for a little while. Build your confidence and get comfortable with
how it works before moving on to cmdlets that change the state of objects like
This chapter only includes basic PowerCLI cmdlets to give you an idea of what you
can do. I also take the opportunity of using these simple commands to show a few
concepts applied to the prompt. To get a complete list of the PowerCLI cmdlets,
type the following command (I recommend to use Out-GridView for better readability):
23
LIST ALL POWERED-ON VIRTUAL MACHINES
WITH THEIR FOLDERS IN A CLUSTER
The best place to start in PowerCLI is to list all VMs in the environment. This cmdlet
is probably one of the most commonly used. It includes a lot of important information
about your servers. Similarly with traditional PowerShell commands, you can use
the pipe " | " to narrow down the results to only what you are after.
In this example we list the cluster named "Management", then we list the VMs
registered in this cluster, then we filter only the ones that have the property
Another simple cmdlet that you’ll find useful displays more about PowerCLI objects in
context this time. As mentioned previously, virtual machine objects contain many
interesting properties, including the host they are running on. In PowerCLI, hosts are
referred to as VMHost.
Name VMHost
---- ------
Test-vm ESX-Host-2
24
The interesting thing with the VMHost property is that, even though the name of the host
is displayed, it contains a VMHost object. Meaning you can obtain information about
the host by working with the VMHost property - no need to retrieve the object with
the Get-VMHost cmdlet. In other words, the following two commands return the same result.
In the first command, we retrieve the VMHost using the cmdlet on the VM object.
$VM | Get-VMHost
$VM.VMHost
Of course, this is not only true for VMHost but also for most object types like clusters,
Note: When using variables, you can’t use $Host as it is already a PowerShell
Now that we touched base on a few basic cmdlets, it is time to start poking around
in the PowerCLI objects so you can be able to find what you are after by yourself.
You can either look it up in the online documentation or explore the object itsel
25
1. VMware cmdlets reference guide
VMware provides a reference guide listing all the cmdlets and properties in PowerCLI.
and object types. For instance, if you want to find information about vSphere port groups.
• Expand the “All Types” tab and find the “VirtualPortGroup” link.
• After clicking the VirtualPortGroup link, you get information about the type.
26
Here we learn that:
PowerCLI objects (on which you can click for more information).
27
2. PowerShell prompt
Now if you don’t want to get out of your PowerShell prompt (good on you!),
you can find the same information with some detective work.
• Start by looking for the cmdlet that will help you find the desired
CommandType Name Ve
----------- ---- --
Cmdlet Get-VDPortgroup 11
Cmdlet Get-VDPortgroupOverridePolicy 11
Cmdlet Get-VirtualPortGroup 11
Cmdlet Get-VMHostProfileVmPortGroupConfiguration 11
As you can see, several cmdlets match the filter, but a quick Get-Help on each of them
will tell you that Get-VirtualPortGroup is the one you are after.
• Next, run the command on a port group and explore the object using
Get-Member. The output will list the properties and methods of the object.
You get basic information on them such as: object type for properties,
$PortGroup | Get-Member
28
The benefit of using the prompt over the online documentation is that you get
to display the value of the properties. This is useful for objects which property
names are not obviously clear at first glance. As you might already know, just like with
cmdlet like Get-VM. This behavior is dictated by special XML files in PowerCLI.
to the cmdlet or variable. You can see below the values of the properties shown
in the Get-Member output. Of course, you will not see the methods as these are actions.
of Select-Object.
29
This screenshot also depicts the warning messages about object deprecation.
DisplayDeprecationWarnings $false".
like Get-VM contains a nicely formatted set of properties that most people will be
interested in about a VM, and you get more properties when you pipe it in “| select *”.
But that’s not all, as you may have realized not everything is available at first glance.
Those cmdlets only return a fraction of the data available for a VM.
30
(highlighted in yellow in the screenshot above). That property offers a convenient
way of interacting with the underlying API and returns a lot more methods and
Note: The Get-View cmdlet returns the same results as the ExtensionData property,
but we won't get into the details of it here as it is a more advanced topic.
property on a VM object. The properties that make up the list contain categories
in which you will find other sub-categories etc. Using this, you have access to information
such as hardware devices, file type locations, guest related information retrieved
by VMware tools, and more! Some might require a little more digging than others
31
CHAPTER 4. WRITING SCRIPTS
Now that we introduced PowerCLI and started using it, let's take a small break
to talk about script quality. When writing scripts, regardless of the language used,
Should you fail to do so, you will make it harder for others and your future self
to understand your scripts and ensure consistency. I cover a few topics here that
may not apply to everyone but are considered best practices. You will find your style
of scripting and figure out what works best for you as you gain experience in this area.
SHORTER IS BETTER
One thing that makes a script enjoyable to read is its optimization. Try to avoid
repeating the same operation several times. For instance, you can usually make it
shorter and more optimized by using a loop that specifies a repeated operation only
once. Start by writing the script, so it does everything you want it to do and then go
through the code and look for opportunities to optimize it, hence making it cleaner.
It might take a bit more time when writing the code but you’ll be thankful you did.
NO HARDCODED VALUES
This one has been repeated so many times already. Scripts should always avoid
32
It is sure to break any time something is changed in the environment, and no one will
remember there is this one script that uses the old value. Now sometimes you may
need to specify values inside a script for various reasons, and it is fine, but there are
• Define all the variables at the top of your script. The rest of the script should
only use those variables to avoid a treasure hunt when something breaks.
be a good idea to consolidate all your statically defined variables into a csv
or xml file that is imported at the start of every script. That way, when you
ERROR HANDLING
This part is maybe the least fun of scriptwriting, but it is a necessary evil.
Including error-handling in your functions and scripts will make them a lot
safer to use and easier to debug. This can be achieved a number of ways,
but the “Try, Catch, Finally” triad is probably the most convenient one.
This method is used in the first of the use cases throughout this document.
33
PSSCRIPTANALYZER
If you want to make sure your scripts follow Microsoft guidelines, you can use
PSScriptAnalyzer to check the quality of your code. I usually don't go that far,
FUNCTIONS
One way of making your script leaner and cleaner is through the use of functions.
is a bit of code that can take parameters (arguments) and return some results.
Writing a function may seem daunting at first, but you’ll soon get used to it.
Function Hello {
Param ($WhoAreYou)
This is obviously a silly example as it serves no purpose, but the reality is not too far
34
WHY USE THEM?
these can be made into a function that is called in one line instead of writing
all the operations again. Should a change need to be made to this section,
amending the content of the function will update it everywhere in the script,
hence reducing the risk of forgetting one of them during your script update.
By placing each main activity inside a function that is parameterized and tested,
the execution script becomes an orchestration script that calls the functions one
PowerShell and PowerCLI offer a wide selection of cmdlets, but some operations
might not be covered by them, or you might want to have the ability to make
something quicker and easier to do. For instance, you could have a function that
on all the hosts. By putting them into your own PowerShell module, you can have
your own functions available in the prompt! The possibilities are endless!
35
FUNCTION BEST PRACTICES
There is a lot to say about functions, in fact they could be the topic of an eBook
all by themselves! For that reason, we will only skim the surface of what you can
and should do with them. For more information, there is a plethora of great content
online that talk about them in greater details. Below are a few guidelines to write
clean functions and help others, as well as your future-self, understand your work.
For cleaner functions, always use the param() block and put the parameter segment
below the title, not on the same line. Doing so will allow you to add attributes to your
parameters. Attributes are a great way to lock down your function to ensure it is used
properly. In this manner, functions can even do some error handling for you.
Function Convert-DSToCanonical {
param(
[Parameter(Mandatory = $True,ValueFromPipeline=$True)]
[VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl[]]
$Datastore
)
Attributes apply conditions to parameters to ensure they are used the way they're
intended. Lots of attributes are available that deal with a variety of needs.
Among them, you can lock a parameter to a specific type, make it mandatory or not,
36
allow only a certain set of values, allow one or multiple values, set a default value,
validate a parameter with a bit of code, give it parameter aliases, prevent sets
of parameters to be used together, and much more! You can find an extensive list
in Microsoft documentation.
[CmdletBinding(DefaultParameterSetName=1)]
param(
[Parameter(Mandatory=$true,ValueFromPipeline = $True,position=0)]
[string]
$Destination,
[parameter(position=1)]
[ValidateRange(1,65535)]
[int]
$Port,
[parameter(parametersetname=2)]
[Alias('t')]
[switch]
$Continuous,
[parameter(parametersetname=1)]
[Alias('n')]
[int]
$Count = 4
It is always best to try and stick to Microsoft's guidelines to make your functions
as intuitive as possible. Follow the verb-noun nomenclature and use approved verbs
(Get-Verb). That way your scripts will have a more “PowerShell feel” to them.
37
CODE INDENTATION
Using indentation greatly helps in understanding the structure of the code and
increases clarity. Any script that is not correctly indented will require extra effort
Here is another one that has been repeated since well before PowerShell existed.
Include as many comments as possible to help others, or your future self understand
your code. Note that you can even create a help page for your functions.
38
RETURN OBJECTS
object and not a string. Returning objects will allow you to use them for other
common names for the property names of the objects returned (like VMHost).
That way, you can make use of the PipelineByPropertyName capability of PowerShell.
39
CHAPTER 5. HOW TO USE SCHEDULED
TASKS AND HTML REPORTS
I grouped these two sections together because they often work hand in hand.
I usually write a script that produces a report in HTML format, and I then store
it on a web server or send it via email. That script is run by a scheduled task,
TASK SCHEDULING
We have all been creating scheduled tasks for a long time now, and everyone
is familiar with it. Here we are covering a nifty convenient way to execute PowerShell
scripts in scheduled tasks. Those scheduled tasks can be used for many things like
for instance.
PREPARATION
• Install the PowerCLI modules at the local machine level or user profile level
40
CREATE A SERVICE ACCOUNT FOR THE SCHEDULED TASK
• Open the Local Security Policy console by typing secpol in windows search
• Launch a PowerShell session as this user and set the execution policy
41
CREATE A FOLDER TO STORE THE SCRIPTS AND APPLY PERMISSIONS
• Create the folder anywhere on the server that makes sense to you (C:\Scripts
for instance).
• Log into the vSphere web client and select the vCenter object.
TEST USER
Connect-VIServer vcsa.test.local
• Make sure you can perform some of the commands you will need
in your scripts.
42
INSTALLING THE SCRIPTS
The idea here is to make scheduling scripts as flexible and as easy as possible.
To achieve this, we have a batch file that runs a PowerShell script of the same name in
the same folder and prints its execution in a log file. It is convenient because
whenever you need to schedule a new script, just copy this batch file in the new
C:\Scripts\ListVMs.ps1
$VCENTER = "vcsa.test.local"
$CSVFile = C:\Scripts\VMList.csv
Connect-VIServer $VCENTER
43
3. Executes a ps1 file with the same name as this bat file (%~n0) in PowerShell
C:\Scripts\ListVMs.bat
CD %~dp0
SET runDate=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%
• Select the task user we created earlier and check "Run whether user
is logged on or not".
44
• Configure the Trigger tab as you want. You can leave it empty for this test
• In the Action tab, leave the default settings and select the batch file.
45
• Leave the rest of the tabs to their default settings unless specifically needed.
HTML REPORTING
Reporting is an important part of managing and automating an environment.
Not only does it give you a wider view, but it also takes things off your hands by
scheduling it. You won't forget small tasks, and you can use your time for more
interesting matters. While most of the vSphere monitoring can be done through
vROPS (vRealize Operations Manager), many companies don't have the budget
PowerShell offers a convenient way to convert objects into HTML code with a single
46
PRODUCING THE HTML REPORT
Let's start from the beginning. First we need to retrieve our VM inventory,
then convert it to HTML, then process it for email, web server or both.
Connect-VIServer vcsa.test.local
name,vmhost,PowerState,memoryGB,numcpu,guest,version
TIP: Add style to your HTML report by creating borders. Write your CSS
in a $Style variable that you pass in the -Head parameter of the ConvertTo-
Html cmdlet. For instance, you could use this to add a background color
Have a look at its documentation if you want to explore this further — which you can
47
PROCESSING THE REPORT
EMAIL REPORT
to your email environment. That way you can re-use it for your next script
$Email = @{
From = "$Env:Computername@test.local"
To = test-user@test.local
SmtpServer = srv-smtp.test.local
Body = $Html
BodyAsHtml = $True
Note 2: The From field is dynamically populated with the name of the server
as address prefix.
Send-MailMessage @Email
48
WEB SERVER
If you want to have the report available at any time in your web browser,
all you need to do is to export it to the web server's www folder with the .html
extension. Note that in order to achieve this, the user running the task must have
write permissions to the www folder. Also, I suggest you add the date and time
of the execution in the web page to know at which point in time this information
was retrieved.
"<h1>$(get-date)</h1>"
$File = "\\srv-web\www\ListVMs.html"
Not the most beautiful report as you can see, but it gets the job done.
Once you have a framework down for nicer reports, you can start working with
more advanced scripts and maybe build an index page with links to the reports, which
is a great exercise.
49
CHAPTER 6. USE CASES
it comes to automation. Deploying virtual machines is a day to day task, but it can
take a lot of time, and IT departments are usually eager to automate this process.
We are going to demonstrate here how to deploy several virtual machines based
on the details stored in a CSV file. However, keep in mind that this is merely
REQUIREMENTS
These requirements are only true for the purpose of this script because I wanted
to keep it as simple as possible. You can make them irrelevant with a few changes
to the code.
50
◦ VMName ◦ Dns
◦ Template ◦ Cluster
◦ IP ◦ Datastore
◦ Mask ◦ Portgroup
◦ Gateway
VMName,template,IP,mask,gateway,dns,cluster,datastore,portgroup
test-
vm-1,W2016Template,10.1.1.5,255.255.255.0,10.1.1.254,10.1.1.1,Clus-
ter_test,vsandatastore,Test-PG
test-
vm-2,W2016Template,10.1.1.6,255.255.255.0,10.1.1.254,10.1.1.1,Clus-
ter_test,vsandatastore,Test-PG
SCRIPT EXPLAINED
The script below does exactly what we just mentioned. I used comments (in green)
Note that this script is sequential, meaning it does things one by one. You can make
these kinds of scripts run faster by using PowerShell jobs running concurrently,
51
######################## SECTION A
# Make errors to be terminating. Otherwise some won't be caught.
$ErrorActionPreference = "Stop"
Try {
$CSVFile = "C:\Users\test-user\Desktop\DeployVM.csv"
$CSVVm = Import-Csv $CSVFile
######################## SECTION B
# Verifying that the input is correct and that the VM name is not already in use.
######################## SECTION C
######################## SECTION D
######################## SECTION E
# Deploying the VM
######################## SECTION F
52
# Connecting the correct portgroup
######################## SECTION G
# Starting the VM
$NewVM | Start-VM
} CATCH {
######################## SECTION H
SECTION A
As part of the error handling to implement, we want the script to stop should
any error occur. In order to achieve this, we use the TRY, CATCH blocks that offer
a convenient and clean solution. However, non-terminating errors are not caught
by the CATCH block and the cmdlets we use here generate some for input check purpose.
Then we use the Import-CSV cmdlet to import the content of the CSV file
Finally, we start a foreach{} block that loops through every record of the CSV file
(picture above).
53
SECTION B
This section serves two purposes. It retrieves vSphere inventory objects for later use
and breaks the execution if the object cannot be found. That way we can ensure that
the user didn’t make a typo in an object name or chose a VM name already in use.
Because it is located inside the TRY{} block, any error that occurs will be caught
SECTION C
a temporary one. The type NonPersistent means that the cloned custom specs are
only available in the current PowerCLI session; it doesn’t appear in the UI and
SECTION D
We now need to configure the cloned custom specs using the input from the CSV file.
In order to do so, we have to use yet another type of object with the Get/Set-
OSCustomizationNicMapping cmdlet. We then use the input of the CSV file to set
the properties.
SECTION E
The groundwork is done so we can now deploy the VM with the cloned custom
specs, template, and resources configured in the CSV (datastore and cluster).
The prompt will stay on hold for the duration of the deployment with a progress
bar before moving on to the next step. Once the VM is created, the inventory object
54
SECTION F
By default the VM created sits on the same network port group as the template it
originates from. Any hardware changes (CPU, memory, disk…) should be done here,
including the port group that was part of the CSV input.
SECTION G
The VM is here and configured. It is time to power it on. Once the VM boots up,
it will start the guest customization following the cloned custom specs we created
After vCenter initiated the VM power on, the script moves on to processing the next
SECTION H
If any error occurs within the TRY{} block, it is intercepted and processed in the Catch{}
block. Here the $_ variable contains the error encountered which Exception property
contains the description of the problem. Ending up here means the script will display
There are different schools of thought as to how error handling should be performed.
Some prefer to break the current loop and move on to the next record to process,
my inputs. No right or wrong answer here, a good old “it depends” as usual.
55
MANAGE VSPHERE TAGS
It wasn’t easy selecting which use case to cover and which to leave aside in this book
as so much can be done in PowerCLI. I chose to talk about vSphere tags because they
offer such flexibility and can greatly simplify automation. They are similar to attributes,
like metadata you apply to vSphere objects in the inventory, allowing you to create
Tags that are related to each other are assigned to a category that can only contain
one type of object tag (virtual machine, host, datastore…). Categories have a cardinality
property that defines whether more than one tag in the category can be applied
to an object.
The Entity types you can use for a tag category are the following: All (default), Cluster,
When setting the Cardinality, "Single" means that only a single tag from this category
EntityType VirtualMachine
Test-Servers Multiple
56
CREATE TAGS
Create as many tags as required and assign them to the category. You can also use the
PS C:\> New-Tag -Name Test-Server-Web -Category Test-Servers -Description "Web test servers"
57
ASSIGN THE TAGS TO VMS
Now tag the VMs. As you can see below the VM object can be fed from the pipe
to the cmdlet:
Tag Entity
--- ------
Test-Servers/Test-Server-DB srv-test-db
Tag Entity
--- ------
Test-Servers/Test-Server-Web srv-test-web
It is now possible to retrieve vSphere inventory based on the tags assigned to them.
The -Tag parameter is available on all vSphere object types that can be tagged:
58
PS C:\> Get-VM -Tag Test-Server-DB
vSwitches. The former lets you create a port group quickly on all hosts that are part
of the vSwitch. However, standard switches are often used due to license restrictions
or simply personal preferences. With that in mind, adding port groups to standard
This can be done a lot faster using PowerCLI instead of the web client.
• Retrieve the vSwitches on which you want to create the port group
I stored the vSwitches in a variable to make the command shorter and easier to read.
59
PS C:\> $vSwitches | New-VirtualPortGroup -Name "Test-PG" -VLanId 900
However, you can use it in the pipeline as it means each record is processed
one after the other. You can find in the help page of the cmdlet which object
60
MONITOR VM CPU USAGE IN NEAR REAL-TIME
In this use case, we are going to play a little bit with the progress bar capabilities
of PowerShell and discover the PowerCLI cmdlet to get performance data. We want
to monitor the CPU usage of a VM in near real-time, which is every 20 seconds in vCenter.
First, we will learn how to retrieve the correct stats about a VM, and then we will see
Some resource usage values like CPU data can be retrieved quicker in the ExtensionData.
RETRIEVE STATS
PowerCLI includes the Get-Stat cmdlet that returns statistical information available
on a vCenter server. The Get-StatType cmdlet allows you to list all the available
• List the counters that can be retrieved and find the one you need
61
Get-StatType -Entity $VM
cpu.usage.average
cpu.usagemhz.average
cpu.ready.summation
mem.usage.average
mem.swapinRate.average
mem.swapoutRate.average
mem.vmmemctl.average
mem.consumed.average
mem.overhead.average
disk.usage.average
disk.maxTotalLatency.latest
net.usage.average
sys.uptime.latest
disk.used.latest
disk.provisioned.latest
disk.unshared.latest
to save space in the database. The latest 5 minutes period contains the real-time
62
If you add the -RealTime switch to the command below you will get a lot more available
counters, just like you would in the performance tab of the vSphere Web Client.
Real-Time
Last day
63
• Retrieve the real-time performance data of the VM with this counter:
that there are MHz per core (instance number), MHz global (no instance number),
PROGRESS BAR
It may look like a gadget to some, but the Write-Progress feature of PowerShell
is pretty neat for building a visual depiction of information inside the PowerShell
prompt. The progress bar is usually used to track installation or script steps,
64
but you can trick it into displaying any kind of values you want formatted as a bar,
provided you can make it a percentage. For our particular case, in order to make it
act like real-time monitoring, the command will have to run inside a loop.
• Make a loop that runs every 20 seconds (interval for real-time counters)
while ($true) {
sleep 20
while ($true) {
sleep 20
while ($true) {
sleep 20
• Run the code and enjoy the view. It only refreshes every 20 seconds,
65
MONITOR MULTIPLE COUNTERS
We can also add other counters to the progress bar stacked under the VM name.
We need to make a few changes to the code. And to make things more interesting,
Progress bars can have an ID and a parent ID. You can stack multiple progress bars
under another one by specifying a Parent ID. In the example below, we added
the memory usage that we stacked with CPU usage under the name of the VM.
Below is the modified code with added comments. Notice the ID and ParentID
parameters.
Function Invoke-VMMonitor {
param(
[parameter(position=0,Mandatory=$True)]
[VMware.VimAutomation.ViCore.types.V1.Inventory.VirtualMachine]
$VM
)
while ($true) {
# Wait interval
sleep 20
}
}
66
Because it is a function, it is now much easier to run.
machines are made of objects that are stripped or mirrored across multiple hosts to
or following a failure, the VMs that have objects stored on this host become non-
a rebuild of these objects is initiated to restore the compliance with their storage policies.
67
These rebuilds can put a lot of stress on the disks hence reducing their life expectancy
and adds CPU overhead during the processing. To avoid such an event occurring
• Then we can modify the setting by using the Set command. Some operations
like this one require that you confirm in order to proceed. You could bypass
Perform operation?
Modifying advanced setting 'VSAN.ClomRepairDelay'.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"): y
68
CHAPTER 7. RUNNING ESXCLI COMMANDS
IN PowerCLI
to perform various administrative tasks and manage many aspects of the host with
where traditional means are not available, for instance. These can be run when
logged in the interactive shell (DCUI), in SSH sessions, with vCLI, and as we’re about
to discover, in PowerCLI!
Even though PowerCLI offers more than 600 cmdlets, there is still a large number
of tasks that can only be performed with ESXCLI. To fill that gap, VMware provided
the great Get-EsxCLI cmdlet that allows you to run ESXCLI commands from within
PowerCLI. It can be a very powerful cmdlet when used in functions or automated scripts.
arguments. Meaning you had to specify every single argument in the right order,
including NULL where no value was required. The -V2 switch was introduced
69
BROWSING ESXCLI
To start using ESXCLI, run the cmdlet with the -V2 switch, a vSphere host as a parameter
and store it in a variable that we will name $EsxCLI. Then display the content of the variable.
As you can see, it is similar to what the ESXCLI command would output in an SSH session.
You can then browse through the $EsxCLI variable just like you would with ESXCLI.
70
RUNNING COMMANDS
While browsing through the ESXCLI categories is fairly simple, running commands
differs slightly. Everything is done through the use of methods that we will describe below.
HELP()
The first one is pretty self-explanatory. You can run this method against any
ESXCLI object in PowerCLI just like you would in ESXCLI. Take the VIB subcategory,
PowerCLI
$EsxCLI.software.vib.help()
SSH
71
INVOKE()
This method runs the ESXCLI command against a vSphere host. It is comparable
can be run by simply typing ".Invoke()" at the end of the command. For instance,
NOTE: I added "| Format-Table" to compare it with esxcli in ssh, you will see
PowerCLI
$EsxCLI.software.vib.list.Invoke() | Format-Table
SSH
CreateArgs()
This method is to be used when you need to invoke an ESXCLI command with
arguments. This is where the introduction of the -V2 switch changed things.
72
It is now really easy to create an argument object and populate each of its properties
before passing it to the Invoke() method. For this example, we are displaying
PowerCLI
As you can see, only one argument is available to specify the name of the uplink
(nickname):
PS C:\> $Arguments
Name Value
---- -----
nicname Unset, ([string])
PS C:\> $Arguments
Name Value
---- -----
nicname vmnic0
73
• Invoke the command with the arguments object
$EsxCLI.network.nic.get.Invoke($Arguments)
SSH
74
CHAPTER 8 . FINAL THOUGHTS
VMware went to great lengths in providing the community with a convenient way
In these times of cloud and automation, learning advanced scripting has never been
more relevant. PowerCLI is an incredible tool for everyone to have in their toolbox,
and it unlocks many doors you didn’t even know existed before you started using it.
In this paper, we barely scratched the surface of what PowerCLI can do. We explained
several core concepts and demonstrated several use cases ranging from beginner
to medium/advanced usage. While PowerCLI was indeed the main focus, most
After reading this e-book, try to find use-cases for PowerCLI in your environment.
Be sure to spend some time experimenting with new scripts and always keep trying to
is to avoid using pre-existing scripts when there is one that fits your need. Instead,
try to write it yourself. It may take more time, but you will learn quickly and prepare
yourself well for when you really need to do it. If you get stuck somewhere, there is
nothing wrong with having a peek at that script you found online to see how he/she
did it or ask on the VMTN forums, that’s also how you learn!
Once you get comfortable with PowerCLI and end up writing that one awesome script
that changed your vSphere admin life, make sure to share it with the community!
Xavier started his IT career in the early 2010's and evolved from a Windows SysAdmin
technologies for a large customer. Xavier is also a 4 time VMware vExpert and holds
VMware VCP certifications. He grew a passion for scripting and automation ever since
he started using PowerCLI which offers a fine balance between technicity and creativity.
Xavier also always tries to give back to the online community as much as possible
on his blog and the VMware forums by sharing his knowledge and various scripts;
76
Altaro VM Backup - Trusted by over 40,000 SMBs
Altaro VM Backup for VMware & Hyper-V is hassle-free and affordable virtual machine backup solution.
Virtual machine backup software packed with powerful features for VMware and Hyper-V.
View features
Altaro Office 365 Backup for MSPs
enables you to back up and restore
all your customers’ Office 365
mailboxes through a centralised
multi-tenant online console,
on a monthly subscription.
Developed for Managed Service Providers (MSPs), Altaro Office 365 Backup for MSPs enables
you to provide your customers with backup and recovery services for Office 365 mailboxes,
backing up their Office 365 emails to Altaro’s Microsoft Azure infrastructure.
Benefits of the Altaro Office 365 Backup for MSPs subscription program
www.altaro.com
ABOUT ALTARO
Altaro Software is a fast-growing developer of easy-to-use backup solutions which backs up
and restores both Hyper-V and VMware-based virtual machines, built specifically for
MSPs and SMBs customers with up to 50 host servers. Altaro take pride in their software
and their excellent level of personal customer service and support, and it shows.
Founded in 2009, Altaro already services over 40,000 satisfied customers worldwide and
are a Gold Microsoft Partner for Application Development and Technology Alliance
VMware Partner.
FOLLOW ALTARO
Subscribe to the VMware DOJO and receive best practices, tips, optimization guides
Take your training to the next level on the Altaro Forums! Browse topics, read answers
80
PUBLISHED BY
Altaro Software
http://www.altaro.com
All rights reserved. No part of this book may be reproduced or transmitted in any form
or by any means without the prior written permission of the publisher or authors.
Every effort has been made to make this book as complete and as accurate as possible,
but no warranty or fitness is implied. The information provided is on an “as is” basis.
The authors and the publisher shall have neither liability nor responsibility to any person
or entity with respect to any loss or damages arising from the information contained
in this book.
FEEDBACK INFORMATION
We’d like to hear from you! If you have any comments about how we could improve
the quality of this book, please don’t hesitate to contact us by visiting www.altaro.com
sam@altarosoftware.com
81