PowerShell study guide – core concepts

This course will introduce the core concepts of PowerShell in order to make the most out of PowerCLI.

Being proficient in “PowerCLI” could be summarised in this way:
70% Know PowerShell core concepts relevant for PowerCLI
30% Understand the concepts specifics to PowerCLI
And as prerequisite, understand VMware technologies

The focus of this study guide will be on these 70%.
The other 30% will be covered in the PowerCLI study guide – core concepts

Scope of this course

Think of PowerShell as a foreign language, it will takes years to be fluent and there will be always something new to learn.
However, in only few months it is already possible to have a basic conversation.
This is the goal of this course, it is on purpose limited in scope to let you focus on what is essential.
It will rely heavily on the official PowerShell documentation but presented in an order that will make sense for a beginner and skip the areas that are not useful in a PowerCLI context.
Practice is needed to learn PowerShell, so there will be no screenshot of the result of a command.
Each topic will be introduced with at least one example and one link to the official documentation.
You will need to study this documentation and practice yourself to be “fluent” in each of them.
In others words this course is not self-standing, but more an “enhanced table of content” of what you need to know and in which order to get a strong foundation before starting to work on PowerCLI.
If you prefer a self-standing course that you can study offline I would recommend the books in the appendix
However, be aware that they will introduce concepts that you don’t need for PowerCLI.

PowerShell on Linux will be out of scope.

PowerCli in context

PowerCLI in context
The above diagram is extracted from “PowerCLI study guide from rookie to guru
PowerCLI could be considered as an “extension” from PowerShell and PowerShell is built on top of “.Net”
This is why you need to learn PowerShell and “.net” in order to make the most out of PowerCLI

List of core concepts


A windows workstation with latest version of Powershell installed.
Some features are only available in more recent version and some bugs have been fixed.
An editor to write you script, I am still using “notepad ++” even if there are probably better options nowadays.

How to handle each concept

Each PowerShell concept that i consider useful for PowerCLI will be presented briefly.
It is mandatory to type the commands in a PowerShell session to get some practice and discover the result by yourself.
You will also need to read the documentation associated and practice on your own until you really understand the concept.

What is PowerShell / Object-Oriented Programming Concepts / cmdlet / On top of .Net

The definition in “What Is PowerShell” is a good introduction
Windows PowerShell is an interactive object-oriented command environment with scripting language features that utilizes small programs called cmdlets to simplify configuration, administration, and management of heterogeneous environments in both standalone and networked typologies by utilizing standards-based remoting protocols.

The key word is “object-oriented”, so many concepts of Object-Oriented Programming are applicable to PowerShell.
Programming Concepts (Focus only on Object, Class,Inherirance)
Object-orient programming
You should now understand the concept of “objects”

Everything in the real world can be represented as objects.
A car is often used as an example to introduce objects concepts.
Any car has:.
Static properties: Brand = Renault / Model = 4L
Dynamic properties: FuelInTheTank = 10L
Method: Brake/Accelerate/Top up fuel
Properties are information about the objects.
Method are what can be done to the object, in this case we can use the method “top up fuel” to increase the dynamic property FuelInTheTank to 20L
However the brand is a static property, it will never change.
All cars will share properties and methods, so instead of defining from scratch each object we often start from a “template” a “Class” in that case.
A class will have many properties and method. We can then create new “objects” or “instance” by filling only the necessary properties; for example, we can create many identical cars and modify only the static property serial number.

Maybe you would like to create electric and fuel car objects.
A FuelInTheTank property will not make sense in an electric car, however an electric car share most of others properties with any other car, like having a brand, model, serial number etc.
In that case you may want to have a class “car” with the properties Brand,Model
A new class “electrical car” inherited from “car” that just add the property “BatteryCharge”
A new class “fuel car” inherited from “car” that just add the property “FuelInTheTank”

Then there was the key-word cmdlet
You can do much more than just using the “methods” in a car to manipulate an object, you can for example use function or cmdlet against a car object:
drive the car “Car 1” from “City A” to “CityB”
In powershell it could be a function or cmdlet that could be called like
DrivertheCar –car “Car 1” –from “CityA” –to “CityB” the function in that case has three parameters, the car, the starting city and destination city.

Another point to be aware is that PowerShell is built on top of “.net”
It means that you can work with “.net” from PowerShell, which is, in some cases, more efficient than what is available in PowerShell
It also means that issues with “.net” will impact “PowerShell” and “PowerCLI

This was a lot of theory but you really need to understand it.
You can for example practice with the real world and try to repesents things or people around you as “object” with properties and methods and create the appropriate classe or subclasses.


Launch “Windows PowerShell” and type the following command


We will never use “Windows PowerShell ISE” on this course.

Get-Process is a CMDLET.
All CMDLETS have the same format “verb”-“noun”
There are a lot of CMDLETS this CMDLET give you the list of all process running on your machine.

To be more precise the command Get-Process has created an array of “System.Diasgnostics.Process” objects and then has displayed some information in our prompt.
The choice of which properties and how they are presented has been made for you.
It is possible to modify this default behaviour but I never get a need for that so far.
This is what i considered an advanced topic not needed to start with PowerCLI

To list all “verb” approved


Approved Verbs for Windows PowerShell Commands
To list all PowerShell command available by default (if you have not modified any settings)


I will recommend to use show-command if you just want to find quickly a command based on the name, and or module.
Use get-command for more advanced search like based on “ParameterType”

Approved Verbs for Windows PowerShell Commands


Get-Process | select-Object -first 1

The “|” means that we transfert all “objects” from the command get-process to another command.
PowerShell is really easy to use with pipe and objects.
The command “select-Object -first 1” means that we want to select only the first object returned by get-process
Then some properties about this “object” that have been selected by default are displayed.


Get-Process | select-Object -first 1 | select-object -property n*

Here we are piping the resulting object to another “select-Object” to display all object properties that start by the letter “n”
* is a wildcard this is another concept that you must be familiar with.


GET-MEMBER / Gettype

Get-Process | select-Object -first 1 | get-member

Get-Member is how you can know what are all the properties and methods available for an object.
First you will see on the top “TypeName: System.Diagnostics.Process”
It means we are dealing with an “object”,that this is an “instance”, of a class “System.Diagnostics.Process”
Below you will see everything that is “defined” in this “Instance”
There are two main categories:
Property are “information” about this specific object. For example Id will be the unique process ID number.
Method is “what we can do” with this object. For example here we have the function “KILL” to kill the process, it will be used later.

There is another way to get the type of an object using a “.net” method “GetType” however you cannot use a GetType() after a pipe.

#This is wrong
Get-Process | getype()
Get-Process | $_.getype()
#This is ok
get-process | foreach-object{$_.Gettype().fullname}
(Get-Process | select-Object -first 1).GetType().fullname
#This is not wrong but not useful
#In that case you get a "System.Object" array which is not false but you do not get the type of each object.

Note: Foreach-object will be covered later


Where-Object / COMPARISON OPERATORS / Automatic Variable

start calc
Start CaLc
Get-Process | Where-Object {$_.ProcessName -eq "calc"}

First we start two instances of calculator.
Please note that powershell is NOT CASE SENSITIVE. These two “start calc” have exactly the same effect.
And then we filter all Object and keep only the one where the “ProcessName” property is “calc”
Where-Object “Filter Returned Data” based on specifics conditions. If the test return a “true”, then the object will be selected.
“$_” in this condition represent the current object in the pipe (So one process at a time)
$_ is one of the “Automatic_Variable” only few of them are really needed for a beginner
We want to return only the process that have a ProcessName property equal to “CAL”
-eq means “Equal to” this is a comparison operator.
As mentioned earlier PowerShell is note case sensitive by default but it is possible to make an operator case-sensitive.
“-ceq” instead of “-eq” for example. Read the about for more details.



(Get-Process | Where-Object {$_.ProcessName-eq "calc"}).kill()

Now all process with the name “calc” are killed.
We have used the method identified earlier for this object.
By using .kill(), we are using the method to kill this process.
This a simple method that do not offer any customization (Parameters) so we just call it without any parameters after kill so ().



Get-Process | Where-Object {($_.PriorityClass -eq “Normal”) -AND ($_.HandleCount -lt 300)}
Sometimes you will need to filter on more than two criteria at the same time. You could “cascade” multiple Where-Object but it is more convenient to use logical operators in the “Criteria”
In this case the “criteria” are slightly more complex
We want the property priorityclass to be “Normal”
AND (So both conditions must be valid)
HandleCount below 300
This is called logical operators. You can then create complex conditions with many sublevels.
The () are not mandatory here but recommended to keep the code clear when you will deal with much complex condition like the one below.
(A eq B) -OR ((A -eq C) -AND(D -lt 300))
The key point to remember is that everything between the () is executed first like in algebra.



start calc
start calc
#This is wrong
Get-Process | Where-Object {$_.ProcessName -eq "calc"}
#This is better
get-process -name calc

The objects at the end are the same with the two commands.
However the second command should be faster because we do not need to export information about all process, put the objects in the pipe, and then filter with where-objects.
Take away here:
Be aware of the performance impact of using a “|” in a script. For a small environment, or command that execute fast, maybe you will not notice the difference.
In a large one you will damage the efficiency of the script.
The line that start by # are comments. They are useful to provide information about a script, within the script itself.



get-help get-process
get-help -full get-process

How could you have know that the command Get-process has “name” as a parameter?
Official documentation and get-help
The syntax give you all “set of parameters” acceptable for this function.
You cannot use two parameters at the same time that only exist in two separate sets for example.
You get also information about which parameters are mandatory or not.



Get-Process | select-object -property name,handlecount | sort-object -property Handlecount | Out-GridView
Get-Process | select-object -property name,handlecount | sort-object -property Name,Handlecount | Out-GridView
Get-Process | select-object -property name,handlecount | sort-object -Descending -property Handlecount | Out-GridView

In the first command we have selected only the properties name and handlecount with select-object, and then sorted the result based on HandleCount number using sort-object.
We would have obtained exactly the same result by starting with “sort-object” and then “select-object” .
However it is better to try to reduce as much as possible the number or size of objects going to the next pipe as early as possible in a serie of pipe to improve efficiency.

The sort-object let you sort based on one or many properties.
If you sort on multiple properties, it will first sort on the first property.
In case of identical values for the first property, it will then use the second property to order them
You can use it ascending by default or descending

Out-GridView is a nice way to display a result fast. (You have even some filtering capability)
It has limitation however, it is not possible to copy paste column name for example.
It is more useful while working from the prompt.
For a schedule task it will be easier to generate a CSV file as an output.


Reduce typing / ALIAS

I guess you have used copy paste so far, but otherwise you will have probably noticed that it starts to be a lot of typing.

#Type the command below and press “tab” multiple time.
#You will get all cmdlet that start by "get-pr" one by one
#When you will see "get-process", just type space. It works also for all properties
#Type the command below and press “tab” multiple time.
get-process -

This is part of about_Line_Editing

Get-Process | select-object -property name,handlecount | sort-object -property Name,Handlecount | Out-GridView
#The command above is identical than the command below
Get-Process | select name,handlecount | sort Name,Handlecount | ogv

For many functions it is possible to reduce the amount of code because the function can be “smart” and identify how to use the parameters based on the type or the position of the parameter.
This is part of about_Parameters
Use the full command and parameters when writing scripts. It will make the script easy to read by other people, even for you if you are coming back to your own scripts few months after.
It will also prevent errors.

Finally, you can also use ALIAS. In that case OGV is an alias for Out-GridView and Select is an alias for Select-Object
Never create your own alias. It will be more difficult to execute the script on another system.
Execute “Get-Alias” to know the default alias, especially % and ?, because some people may use them.
Avoid using the “default” alias on your scripts, it makes the script complicated to read for someone who is not aware of them.
Some of them however are so widely used that you can use them. You will discover them with experience but stick to the full name initially.


Export CSV / IMPORT-CSV / Special Characters

New-Item c:\temp -type directory
Get-Process | select name,handlecount | Export-Csv -delimiter "`t" -path "C:\temp\AllProcess.csv" -NoTypeInformation
notepad "C:\temp\AllProcess.csv"
Import-Csv -delimiter "`t" -path "C:\temp\AllProcess.csv" | ogv

The first line create a new folder “temp” in C:
The second export the list of process, only name and handlecount proeprty in a CSV file in “C:\temp\AllProcess.csv”
However this is not a “Coma separared value” I am using here “`t” which is a TAB
This is one of the about_Special_Characters
I pick this one for three reasons:
It is one delimter that can be used by default while importing text to excel.
Often we can have text that contains alreay , or ; in the objects that we want to export.
It removes the problem of “region”

Some people will use –UseCulture instead of “-delimiter “`t” ”
It will probably work as long as you export or import the file from computers with the same culture.
On my computer “Norwegian” (Get-Culture).TextInfo.ListSeparator give me “;”
An american computer will give you a “,”
Tab will always be tab regardless of the region
Always us the “-notypeInformation” or you will end up with a useless line at the top of the file.

Then use “import-csv” to retrieve information from the file and pipe to ogv to display the result.
You have to be consistent with the parameters used for the export and import.
If you have used -useculture, use it again. If you have used a delimiter use the same one.

If there is already a folder C:\temp an error message will be triggered
New-Item : An item with the specified name C:\temp already exists.
We will see later how to handle errors in your scripts.


Create Variable / Basic String manipulation / Quoting Rules

$TestString = "My test string"
$TestString = $TestString + " appended to the end"

A variable is a temporary storage of data.
Here we have created a variable “TestString” and we have put text on it.
$ is not part of the variable name, it just means that we want to deal with the “content” of the variable
With “=”, one of the assignment operator we have assigned the string “My test string” to it.
Then we have “modified” the variable, by assigning the content of itself + some text appended.
But if you have read the About Assignment operator you will know that we can reach the same result with

$TestString = 'My test string'
$TestString += ' appended to the end'

Do not use a variable name, that is already in use as a variable system. For example $Host it will make a mess.

$i = 5
"The value of $i is $i."
"The value of $(2+3) is 5."
$i = 5
'The value of $i is $i.'
'The value of $(2+3) is 5.'

Surprising result,isn’t it?
So with ‘’ you copy the text as is.
With “” PowerShell will try to interpret the content.
Closely linked to

$MyProcess = Get-Process | Select-Object -First 1
#The command below doesn’t provide the process name as it would have been expected.
“TEST $MyProcess.Name"
#The two commands below provide the expected output. But this is a BAD workaround.
$ProcessName = $MyProcess.Name
“TEST $ProcessName "
#This is the correct way to display a property in a “text”
“TEST $($MyProcess.Name)"

The above example will spare you some frustration, I discovered it too late on my own learning.
If you would like to display only the property value of an object in a “string” you can’t do it like in the first example.
The third way is the proper way and is based on the “Operator_Precedence”


Basic Number manipulation

$TestNumber = 3
$TestNumber + 2
$TestNumber / 2
$TestNumber * $TestNumber
$TestNumber % 2

This is straightforward.

Strong type variable

$TestNumber = 3
$TestNumber = "i can put a string here"
[int]$TestNumber2 = 10
$TestNumber2 = "i can't put a string here"

Forcing variable to be of a certain type can prevent issues in your scripts.
Especially when using stong type in parameters of functions.

Advanced text manipulation

$NewStringTEST = "small_12345"

This topic is “very big”
You can start by looking at the “System.String” Class to see all “Methods” defined in a string object String Class

You have probably noticed that the documentation is sometime from the .net and not from powershell.
The reason is that PowerShell is built on top of .net and you have access to everything in .net from PowerShell
You will probably not need split and join initially…but it is good to know them.

$Text1 = “some text”
$Text2 = “SOME TEXT”
$Text1 –eq $Text2

The above commands is a reminder that by default PowerShell is NOT case sensitive.
So how can you compare this text?

$Text1 = “some text”
$Text2 = “SOME TEXT”
$Text1 –ceq $Text2

“c” before the “eq” make the operator eq case sensitive…
But you should already know that if you have learned the Comparison Operators as instructed earlier 😉


Advanced Number manipulation

$TestNumber = 10

Again this is a big topic.
I just want to point out here the “MATH” class. It is based on “.Net”
Take away:
Maybe what you need is already available in .”Net”, a script will be much slower if you have to recreate in PowerShell something already existing in “.net”

Math Class


$ProcessArray = Get-Process

An array is a variable that can contains one or multiple objects
They don’t necessary have to be of the same type.


To access the first element of an array. Numbering start from 0.
So your first element is 0 and the last element is (total number of object – 1)


This is the second elemnt of the array


This is another way to get the last element of an array if you don’t know the total number of objects


This is the object before the last object.

$ProcessArray[0,3 + 4..6]

Get the element [0] [3] and [4][5][6]

$Arraytest = @(“A”,2,”C”)

An array can contains “Different kind of objects”

$Arraytest2 = “A”,2,”C”

It is also possible to reduce the typing, Powershell will understand the , as different objects to put in a table.

$Arraytest3 = @(get-process)

And then you can count the total number of element in the array.

$arraytest2[0] = “TEST”

You can modify a value

But is is not possible to add or remove element to a PowerShell array
You can use

$ArrayTest2 += “Another Element”

But in this case you are telling PowerShell to create a new array, copy the content of the initial array and add an element.
This will be slow.
There is also no way to remove an object from a PowerShell array without filtering the content of an array and copy to another one.

However is it possible to use a .net array list. (For advanced used only)

$Arraytest3 | get-member
get-member -inputobject $Arraytest3

If you want to see all properties and method for an array you can’t use pipe and get-member. It will give you properties of the objects in the array.
However, you can use instead the parameter inputobject for get-member

[int[]] $TestArray = 1,2,3,4
[int[]] $TestArray = 1,2,3,”TestString”

You can also create an array with strong type.
This is especially useful when for functions parameters to ensure that the use is putting the right information

$EmptyArray = @()

This one is useful to bring back an array to an empty array.
There is also multidimensional array…just know that it exist but so far I never found a need for it in any of my scripts.

ArrayList Class – Advanced user only


$hash = @{ Number = 1; Shape = "Square"; Color = "Blue"}
$hash2 = [ordered]@{ Number = 1; Shape = "Square"; Color = "Blue"}

A hash table, also known as a dictionary or associative array, is a compact data structure that stores one or more key/value pairs.
For example, a hash table might contain a series of IP addresses and computer names, where the IP addresses are the keys and the computer names are the values, or vice versa.

So here we have created two hash table one standard and one ordered (only since PowerShell 3).
A hashtable ordered doesn’t have all the methods available for a standard hashtable.
I use ordered when I need to create an object with properties in a specific order.
I use standard, if I am planning to manipulate the table, like adding or removing key.

What can we do with these hashtable?

get-member $hash

List all keys and value.


Extract just the value for the key requested

$hash["Software"] = "Visio"
$hash += @{Software3 = “Visio3”}

Add elements

NEVER use any space or special characters in a key…it will make the code more complicated.


Remove an entry from a hash table is much easier than with an array.

$hash.software2 = “New Software”

Create a new key and the associated value


You can also check if a key is already in the table

#Case sensitive for the above command
#The above command doesn’t work with Ordered HashTable

As you can see there is a difference between Ordered and standard hashtable.



Hashtable are very useful and a foundation for splatting
Splatting is a method of passing a collection of parameter values to a command as unit. Windows PowerShell associates each value in the collection with a command parameter.

“My test” | out-file “C:\Temp\mytest.txt”
Copy-Item -Path “C:\Temp\mytest.txt” -Destination “C:\Temp\mytest2.txt”
$HashArguments = @{ Path = “C:\Temp\mytest.txt” ;Destination = “C:\Temp\mytest3.txt”}
Copy-Item @HashArguments

In this scenario, the second way is more complicated, you need two lines instead of one.
However in some cases, if you don’t know in advance what parameters will be used or not, it is more efficient to create the $HashArguments based on conditions. (Adding each time new value to the hashtable) and only at the end execute once the command using the $HashArguments.
This is what is used in “ESXi get CIM via vCenter PowerCLI” with the @CimSessionOptionParameters hashtable.



for($i=1; $i -le 10; $i++){$i}

The For statement (also known as a For loop) is a language construct you can use to create a loop that runs commands in a command block while a specified condition evaluates to true.

Here $i start at 1, at the beginning of each loop we check if $i is equal or below 10.
At the end of the loop, the “repeat” action will be executed. Here this is like having

for($i=1; $i -le 10;){

At the “11 loop”, the condition will not be “true” and the loop will not be executed another time.

for($i=1; $i -le 10; $i++){
If($i –eq 5){
$I = 11

It is possible to stop the loop earlier however if the condition is not true at the beginning of the loop.



$i = 1
while($i -le 10){

The above command will give similar result than the previous example in the loop “FOR”.
The While statement (also known as a While loop) is a language construct for creating a loop that runs commands in a command block as long as a conditional test evaluates to true.
The While statement is easier to construct than a For statement because its syntax is less complicated.
In addition, it is more flexible than the Foreach statement because you specify a conditional test in the While statement to control how many times the loop runs



Do{$i;$i++} while($i -le 10)
Do{$i;$i++} until($i –gt 10)

The Do keyword works with the While keyword or the Until keyword to run the statements in a script block, subject to a condition.
Unlike the related While loop, the script block in a Do loop always runs at least once.
A Do-While loop is a variety of the While loop. In a Do-While loop, the condition is evaluated after the script block has run. As in a While loop, the script block is repeated as long as the condition evaluates to true.
Like a Do-While loop, a Do-Until loop always runs at least once before the condition is evaluated. However, the script block runs only while the condition is false.
The Continue and Break flow control keywords can be used in a Do-While loop or in a Do-Until loop.

I have personally never see a use for a “DO” loop, but if you need the loop to be at least executed once it could make sense to use it.



$ArrayProcess = get-process
Foreach($Process in $ArrayProcess){ $Process.Name}
Foreach($Process in $ArrayProcess){

The Foreach statement (also known as a Foreach loop) is a language construct for stepping through (iterating) a series of values in a collection of items.
You can use multiples lines in a script block. I prefer the notation in the second example.
It is easy to identify where is the starting command associated to the closing “}”

get-process | foreach{$_.Name}

Foreach used after a PIPE is an alias to FOREACH-OBJECT
This is very confusing

# This is not working
Foreach($Process in (get-process)){
} | sort name

A “standard” foreach will prevent another pipe

#This is working
get-process | foreach-Object{$_ } | sort name

Within the script block, use the $_ automatic variable to represent the current object.



$a = 10
If ($a –eq 10)
Write-Host "The value is equal to 10”
} elseif ($a –gt 7)
Write-Host “The value is above 7”
} Else
Write-Host “The value is not above 7”
$a = 8
#Repeat the previous block starting from if up to }
$a = 2
#Repeat the previous block starting from if up to }

You can use the If statement to run code blocks if a specified conditional test evaluates to true. You can also specify one or more additional conditional tests to run if all the prior tests evaluate to false. Finally, you can specify an additional code block that is run if no other prior conditional test evaluates to true.
if ()
[elseif ()
You can have many else if.

If a test is “true”, the script block will be executed and the next conditions will be ignored.
If a test is “false”, the next condition will be checked.
If all test are false the “script block” associated to else will be executed
If there is no “ELSE” then, no script block will be executed

It is not possible “copy paste” the syntax from the official documentation to the PowerShell prompt.
This is why i have added else or elseif at the same line as the previous “}” to allow a copy paste to the prompt.
However you will not have this issue if you copy the code in a function.

$i = 10
If($I –is [int]){“This is of type int”}
If($I –is [string]){“This is of type string”}Else{“Not a String”}

Testing the type of an object is quite common, and in that case you will need a type operator.



switch (3)
1 {"It is one."}
2 {"It is two."}
3 {"It is three."}
4 {"It is four."}

Depending of the case a switch can prevent you to have many cascading IF and ELSEIF.

To check multiple conditions, use a Switch statement. The Switchstatement is equivalent to a series of If statements, but it is simpler.
The Switch statement lists each condition and an optional action.
If a condition obtains, the action is performed.

Switch can be very flexible…and complex, check the help for more details.


Execution Policy and Signing

#run powershell as administrator
Set-executionpolicy RemoteSigned

This course is to be used as a foundation for PowerCLI. For some operating system the default settings for the execution policy is “Restricted”. If you try to launch PowerCLI on this system you will get an error like
Microsoft.PowerShell_profile.ps1 cannot be loaded because running scripts is disabled on this system

Learn what are the difference between all Execution Policies and pick one based on your security needs.
Please be aware that it is possible to sign your own scripts with a self-signed or public certificates, however I doubt that a beginner will need that.



Function Add-Two{
($Number + 2)
Add-Two –Number 3

What you see above is a very simple function called “Add-Two” that simply add 2 to the number provided as parameter.
An easy way to think of function is to consider them as “home made” cmdlets.
They can act like cmdlets but are not cmdlets.
Compiled cmdlets are .NET Framework classes that must be written in a .NET Framework language such as C#.
In contrast, advanced functions are written in the Windows PowerShell script language in the same way that other functions or script blocks are written.
Function can be simple as the one above, or slightly more complicated Get-EsxCli on steroids V2

This topic is complex, so start by creating small functions, and get inspiration from others functions. Then start to study all advanced topics.
You will also need to learn about the concept of “recursive function”.
A recursive function is a function that is calling itself.
You can have for example a function that takes as a parameter a folder and list all files in it and then for each subfolder call the same function (Itself/recursion) for this subfolder.
At the end you will get all files in the top folder and all subfolders.



function TEST-COPY{
Copy-Item -Path $SourcePath -Destination $DestinationPath –erroraction Stop
“There is an error”
“This one will be displayed all the time.”

TEST-COPY –sourcePath “C:\Temp\mytest5.txt” –Destinationpath “C:\Temp\mytest6.txt”
“Message associated to latest error: $($Error[0].exception.message)”

“My test” | out-file “C:\Temp\mytest5.txt”
TEST-COPY –sourcePath “C:\Temp\mytest5.txt” –Destinationpath “C:\Temp\mytest6.txt”

If you create advanced functions you will need to handle errors.
Try Catch Finally is here to handle gracefully error
In the “try” section you will put the command that you think will have an issue.
In the “catch” you add what you would like to do if an error is identified in the Try.
The “Finally” section is optional, this is something that will be executed regardless of if there are an error in the try section or not.

One thing to be aware is that this construct works only for “terminating” errors in the “try” section…and I just learned this while working on this tutorial.
You were warned at the beginning, there is always something new to learn with PowerShell 😉
So you need a terminating error, or use the parameter –erroraction “Stop” to make a nonterminating error as a terminating error.

Finally there is $Error which is one of the Automatic Variable.
This is an array of the latest 256 Errors by default with $error[0] the latest error.
Error are objects, so you can use them like any objects, here I am interested in the property .exception.message.
And we have use the $() structure to ensure that we will display properly the property in the Sting.
Refers to the advanced text manipulation for more details.
You may want also to check the “$?” which is also one of the automatic variable.

about_errors ???
In the “about_Try_Catch_Finally” there is a mention of an “about_Errors”
For more information about errors, see about_Errors.
If you know where to find it please let me know, I didn’t find it online, or with get-help after using update-help.

There was a “trap” construct in PowerShell V1.
The good news is that you don’t need to care about it, try catch finally is way better.
And if you see a PowerCLI script using it, it is probably outdated now.

$Null / empty string…a real mess

I normally only say good things about PowerShell…this is the exception.
Checking for null in PowerShell

You will probably end up with many errors with PowerShell related to $Null. For example you can not get a default value of $null for a parameter.
Unfortunately, there are no easy workaround.

One “trick”:
It is not possible to check if a function has been called with a parameter with a $Null value on purpose.
Using “If” you may end up with something not working as expected.
So in that case you can use instead $PSBoundParameters.ContainsKey() like I am using in get-excli on steroids.


Measure-Command {Get-process}

How to check how perform two scripts against each other?
Check the execution time.
As a beginner your first goal will be to get the job done, later on try to optimize.



Congratulations, you have now covered all topics that I considered as mandatory for a PowerCLI beginner and you have been introduced to some of the advanced one.

You should now have enough bases in PowerShell to start the PowerCLI study guide – core concepts

What’s next?

We have only touched the surface of what is possible with PowerShell and .Net, however this is a large part of the 70% you need to know for PowerCLI.
Check the matrix in the appendix to identify others areas that will be useful for advanced users, like regular expression or scheduled tasks.
Later on you may also be interested to learn more topics to manage not only VMware products but also others products like Microsoft Active Directory for example.


Matrix of all relevant PowerShell topics

There are still some useful PowerShell topics for beginner and some that you will need to know when you will reach an advanced level.
I have create a spreadsheet for all “core” topics in the official documentation and classify them by level and usefulness from a PowerCLI point of view.
I have removed the topic that i consider as Useless for PowerCLI
However you can access the complete list of each module by clicking on the title.

For “Useless for PowerCLI” it means that I never had the need to use them so far.
Maybe you will be in a situation where you will need them.
Potentially ALL Powershell command could be useful, if you need to create a PowerShell script that connect to multiples system.
For example connecting to VMware,Active Directory, and send a report by mail.
But in the context of this course everything not directly related to managing VMware technologies will be considered as off topic.

Core About Topics

Topic Description Level Importance
about_Aliases Describes alternate names for cmdlets and commands in Windows PowerShell. Beginner Optionnal
about_Arithmetic_Operators Describes the operators that perform arithmetic in Windows PowerShell. Beginner Mandatory
about_Arrays Describes arrays; a compact data structure for storing data elements. Beginner Mandatory
about_Assignment_Operators Describes the operators that assign values to variables. Beginner Mandatory
about_Automatic_Variables Describes the automatic variables, which that store state information for Windows PowerShell. Beginner Mandatory to Useless
about_Break Explains how to use the Break statement, a statement that immediately exits Foreach, For, While, Do, and Switchstatements. Beginner Useful
about_Checkpoint-Workflow Describes that Checkpoint-Workflow activity, which takes a checkpoint in a workflow. Expert Useful
about_Command_Precedence Describes how Windows PowerShell determines which command to run. Advanced Optionnal
about_Command_Syntax Explains the command format in Windows PowerShell. Beginner Mandatory
about_Comment_Based_Help Explains how to write comment-based help topics for functions and scripts. Advanced Useful
about_CommonParameters Describes parameters that can be used with any cmdlet. Advanced Useful
about_Comparison_Operators Describes the operators that compare values in Windows PowerShell. Beginner Mandatory
about_Continue Describes the Continue statement, which immediately returns to top of a program loop. Beginner Useful
about_Core_Commands Lists the cmdlets designed for use with Windows PowerShell providers. Beginner Optionnal
about_DesiredStateConfiguration Describes the Windows PowerShell Desired State Configuration feature, which helps ensure consistent configuration across multiple remote, managed nodes. Expert Optionnal
about_Debuggers Describes the Windows PowerShell script debugger, a set of cmdlets for debugging scripts and functions. Advanced Useful
about_Do Describes the Do statement, which runs a script block one or more times subject to a While or Until condition. Beginner Mandatory
about_Escape_Characters Introduces the escape character in Windows PowerShell (`) and explains its effect. Beginner Mandatory
about_Execution_Policies Describes the Windows PowerShell execution policies and explains how to manage them. Beginner Mandatory
about_For Describes the For loop in Windows PowerShell. Beginner Mandatory
about_ForEach Describes the ForEach statement, a statement that acts on each item in a collection. Beginner Mandatory
about_Format.ps1xml Describes the Format.ps1xml files that define the default display of objects in the console. Advanced Optionnal
about_Functions Explains how to create and use functions in Windows PowerShell. Beginner Mandatory
about_Functions_Advanced Introduction to advanced functions; the functions that act like cmdlets. Advanced Mandatory
about_Functions_Advanced_Methods Explains how to use the methods and properties that are available to cmdlets in advanced functions. Advanced Mandatory
about_Functions_Advanced_Parameters Shows how to declare parameters for advanced functions. Advanced Mandatory
about_Functions_CmdletBindingAttribute Describes the CmdletBinding attribute, which identifies a function that works like a cmdlet. Advanced Mandatory
about_Functions_OutputTypeAttribute Describes an attribute that reports the type of object that the function returns. Advanced Mandatory
about_Hash_Tables Explains how to create, use, and sort hash tables in Windows PowerShell. Beginner Mandatory
about_History Explains how to get and run commands from the command history. Beginner Optionnal
about_If Describes the If statement, which establishes conditions for an action. Beginner Mandatory
about_InlineScript Describes the InlineScript workflow activity. Advanced Useful
about_Jobs Describes Windows PowerShell background jobs. Expert Useful
about_Job_Details Provides detailed information about background jobs. Expert Useful
about_Join Describes the Join operator, which combines multiple strings into a single string. Beginner Useful
about_Language_Keywords Describes the keywords in the Windows PowerShell scripting language. Beginner Optionnal
about_Line_Editing Describes the editing features of the Windows PowerShell console. Beginner Optionnal
about_Logical_Operators Describes the operators that connect statements in Windows PowerShell. Beginner Mandatory
about_Methods Explains how to use methods to perform actions on objects in Windows PowerShell. Beginner Mandatory
about_Modules Explains how to install, import, and use Windows PowerShell modules. Advanced Mandatory
about_Objects Explains how to work with objects in Windows PowerShell. Beginner Mandatory
about_Object_Creation Explains how to create objects in Windows PowerShell. Advanced
about_Operators The overview topic that describes operators in Windows PowerShell. Contains topics about each operator type. Beginner Mandatory
about_Operator_Precedence Lists the Windows PowerShell operators in precedence order. Beginner Useful
about_Parameters Explains how to working with cmdlet parameters in Windows PowerShell. Beginner Mandatory
about_Parameters_Default_Values Explains how to set custom default values for the parameters of cmdlets and advanced functions. Advanced Mandatory
about_Parsing Explains how Windows PowerShell parses commands. Beginner Useful
about_Path_Syntax Describes full and relative path name formats in Windows PowerShell. Advanced Optionnal
about_Pipelines Explains how to combine commands into pipelines in Windows PowerShell. Beginner Mandatory
about_PowerShell.exe Displays help for the PowerShell.exe command-line tool. Beginner Optionnal
about_PowerShell_Ise.exe Displays help for the PowerShell_ISE.exe command-line tool. Beginner Optionnal
about_Preference_Variables Describes the preference variables that customize Windows PowerShell. Advanced Optionnal
about_Profiles Explains how to create and use a Windows PowerShell profile. Advanced Optionnal
about_Prompts Explains how to create and use a Windows PowerShell profile. Advanced Optionnal
about_Properties Explains how to use object properties in Windows PowerShell. Beginner Mandatory
about_Providers Describes the Windows PowerShell providers and explains how to use the data that they expose. Advanced Optionnal
about_PSSnapins Describes Windows PowerShell snap-ins and explains how to use them to extend Windows PowerShell. Advanced Mandatory
about_Quoting_Rules Explains the rules for using single and double quotation marks in Windows PowerShell, including here-strings. Beginner Mandatory
about_Redirection Explains how to redirect output to variables and text files. Includes redirection operators. Advanced Optionnal
about_Regular_Expressions Explains how to use regular expressions in Windows PowerShell. Advanced Useful
about_Requires Describes the Requires statement, which prevents a script from running without required snap-ins and versions. Advanced Useful
about_Reserved_Words Lists words that are reserved to Windows PowerShell. Beginner Useful
about_Return Exits the current scope, which can be a function, script, or script block. Beginner Useful
about_Run_With_PowerShell Explains how to use the “Run with PowerShell” feature to run a script by right-clicking its entry in File Explorer. Advanced Optionnal
about_Scheduled_Jobs Describes scheduled jobs and explains how to use and manage scheduled jobs in Windows PowerShell and in Task Scheduler. Advanced Useful
about_Scheduled_Jobs_Basics Explains how to create and manage scheduled jobs. Advanced Useful
about_Scheduled_Jobs_Advanced Explains advanced scheduled job topics, including the file structure that underlies scheduled jobs. Advanced Useful
about_Scheduled_Jobs_Troubleshooting Explains how to resolve problems in scheduled jobs. Advanced Useful
about_Scopes Explains how to set and change the scope of functions and variables in Windows PowerShell. Beginner Useful
about_Script_Blocks Explains how to use script blocks to combine expressions, statements and commands into a single code block. Beginner Useful
about_Script_Internationalization Describes the features that make it easy for scripts to display user messages in the language selected for Windows. Advanced Optionnal
about_Scripts Explains how to write and run scripts in Windows PowerShell. Beginner Useful
about_Signing Describes the Windows PowerShell execution policies, explains how to manage them, and explains to how sign scripts so they comply with the execution policies. Beginner Useful
about_Special_Characters Describes the special characters in Windows PowerShell. Beginner Useful
about_Splatting Explains how to use splatting to pass parameters to commands in Windows PowerShell. Beginner Useful
about_Split Describes the Split operator, which splits strings into substrings. Beginner Useful
about_Switch Explains how to use a switch statement to replace multiple If statements. Beginner Mandatory
about_Throw Describes the Throw keyword, which generates a terminating error. Beginner Useful
about_Transactions Explains how to manage transacted operations in Windows PowerShell. Advanced Optionnal
about_Try_Catch_Finally Error handling in scripts is done using the Try, Catch, and Finally script blocks. Beginner Mandatory
about_Type_Operators Describes the operators that work with .NET types. Beginner Mandatory
about_Types.ps1xml Describes the Types.ps1xml files that let you extend the .NET types of objects used in Windows PowerShell. Expert Optionnal
about_Updatable_Help Describes the updatable help system in Windows PowerShell. Beginner Useful
about_Variables An overview topic that explains the types of variables in Windows PowerShell. Beginner Mandatory
about_While Describes While loops in Windows PowerShell. Beginner Mandatory
about_Wildcards Explains how to use the wildcard character (*) in Windows PowerShell. Beginner Mandatory
about_Windows_PowerShell_5.0 Describes features and changes that are new to Windows PowerShell 4.0. Beginner Optionnal
about_Windows_PowerShell_ISE Describes Windows PowerShell® Integrated Scripting Environment (ISE). Beginner Optionnal
about_Workflows Provides a brief introduction to the Windows PowerShell Workflow feature. Expert Useful
about_WorkflowCommonParameters Describes the parameters that are valid on all Windows PowerShell workflow commands. Expert Useful

Core Cmdlets

Name Description Level Importance
Add-History Appends entries to the session history. NA Useles for PowerCLI
Add-PSSnapin Adds one or more Windows PowerShell snap-ins to the current session. Beginner Useful
Clear-History Deletes entries from the command history. NA Useles for PowerCLI
Connect-PSSession Reconnects to disconnected sessions. NA Useles for PowerCLI
Debug-Job Debugs a running background, remote, or Windows PowerShell Workflow job. Advanced Useful
Disable-PSRemoting Prevents remote users from running commands on the local computer. NA Useles for PowerCLI
Disable-PSSessionConfiguration Disables session configurations on the local computer. NA Useles for PowerCLI
Disconnect-PSSession Disconnects from a session. NA Useles for PowerCLI
Enable-PSRemoting Configures the computer to receive remote commands. NA Useles for PowerCLI
Enable-PSSessionConfiguration Enables the session configurations on the local computer. NA Useles for PowerCLI
Enter-PSHostProcess Connects to and enters into an interactive session with a local process. NA Useles for PowerCLI
Enter-PSSession Starts an interactive session with a remote computer. NA Useles for PowerCLI
Exit-PSHostProcess Closes an interactive session with a local process. NA Useles for PowerCLI
Exit-PSSession Ends an interactive session with a remote computer. NA Useles for PowerCLI
Export-Console Exports the names of snap-ins in the current session to a console file. NA Useles for PowerCLI
Export-ModuleMember Specifies the module members that are exported. NA Useles for PowerCLI
ForEach-Object Performs an operation against each item in a collection of input objects. Beginner Mandatory
Get-Command Gets all commands. Beginner Useful
Get-Help Displays information about Windows PowerShell commands and concepts. Beginner Mandatory
Get-History Gets a list of the commands entered during the current session. Beginner Useful
Get-Job Gets Windows PowerShell background jobs that are running in the current session. Advanced Useful
Get-Module Gets the modules that have been imported or that can be imported into the current session. Beginner Useful
Get-PSSession Gets the Windows PowerShell sessions on local and remote computers. NA Useles for PowerCLI
Get-PSSessionCapability Gets the capabilities of a specific user on a constrained session configuration. NA Useles for PowerCLI
Get-PSSessionConfiguration Gets the registered session configurations on the computer. NA Useles for PowerCLI
Get-PSSnapin Gets the Windows PowerShell snap-ins on the computer. Beginner Useful
Import-Module Adds modules to the current session. Beginner Useful
Invoke-Command Runs commands on local and remote computers. NA Useles for PowerCLI
Invoke-History Runs commands from the session history. NA Useles for PowerCLI
New-Module Creates a new dynamic module that exists only in memory. NA Useles for PowerCLI
New-ModuleManifest Creates a new module manifest. NA Useles for PowerCLI
New-PSRoleCapabilityFile Creates a file that defines a set of capabilities to be exposed through a session configuration. NA Useles for PowerCLI
New-PSSession Creates a persistent connection to a local or remote computer. NA Useles for PowerCLI
New-PSSessionConfigurationFile Creates a file that defines a session configuration. NA Useles for PowerCLI
New-PSSessionOption Creates an object that contains advanced options for a PSSession. NA Useles for PowerCLI
New-PSTransportOption Creates an object that contains advanced options for a session configuration. NA Useles for PowerCLI
Out-Default Sends the output to the default formatter and to the default output cmdlet. Beginner Optionnal
Out-Host Sends output to the command line. Beginner Optionnal
Out-Null Deletes output instead of sending it down the pipeline. Beginner Optionnal
Receive-Job Gets the results of the Windows PowerShell background jobs in the current session. NA Useles for PowerCLI
Receive-PSSession Gets results of commands in disconnected sessions. NA Useles for PowerCLI
Register-PSSessionConfiguration Creates and registers a new session configuration. NA Useles for PowerCLI
Remove-Job Deletes a Windows PowerShell background job. NA Useles for PowerCLI
Remove-Module Removes modules from the current session. Beginner Useful
Remove-PSSession Closes one or more Windows PowerShell sessions (PSSessions). NA Useles for PowerCLI
Remove-PSSnapin Removes Windows PowerShell snap-ins from the current session. Beginner Useful
Resume-Job Restarts a suspended job. Advanced Useful
Save-Help Downloads and saves the newest help files to a file system directory. NA Useles for PowerCLI
Set-PSDebug Turns script debugging features on and off, sets the trace level, and toggles strict mode. Advanced Useful
Set-PSSessionConfiguration Changes the properties of a registered session configuration. NA Useles for PowerCLI
Set-StrictMode Establishes and enforces coding rules in expressions, scripts, and script blocks. Advanced Useful
Start-Job Starts a Windows PowerShell background job. Advanced Useful
Stop-Job Stops a Windows PowerShell background job. Advanced Useful
Suspend-Job Temporarily stops workflow jobs. Advanced Useful
Test-ModuleManifest Verifies that a module manifest file accurately describes the contents of a module. NA Useles for PowerCLI
Test-PSSessionConfigurationFile Verifies the keys and values in a session configuration file. NA Useles for PowerCLI
Unregister-PSSessionConfiguration Deletes registered session configurations from the computer. NA Useles for PowerCLI
Update-Help Downloads and installs the newest help files on your computer. Beginner Useful
Wait-Job Suppresses the command prompt until one or all of the Windows PowerShell background jobs running in the session are completed. Advanced Useful
Where-Object Selects objects from a collection based on their property values. Beginner Mandatory

Core Functions

Cmdlet Description Level Importance
Clear-Host Deletes entries from the command history. NA Useles for PowerCLI
Get-Verb Gets approved Windows PowerShell verbs Beginner Mandatory


Utility Cmdlets

Cmdlet Description Level Importance
Add-Member Adds custom properties and methods to an instance of a Windows PowerShell object. Beginner Useful
Clear-Variable Deletes the value of a variable. Beginner Useful
Compare-Object Compares two sets of objects. Beginner Mandatory
ConvertFrom-Csv Converts object properties in comma-separated value (CSV) format into CSV versions of the original objects. Beginner Optional
ConvertFrom-Json Converts a JSON-formatted string to a custom object. Advanced Mandatory
ConvertFrom-String Extracts and parses structured objects from string content. Beginner Optional
ConvertFrom-StringData Converts a string containing one or more key and value pairs to a hash table. Beginner Optional
ConvertTo-Csv Converts objects into a series of comma-separated value (CSV) variable-length strings. Beginner Useful
ConvertTo-Html Creates an XML-based representation of an object. Beginner Useful
ConvertTo-Json Converts an object to a JSON-formatted string Beginner Useful
ConvertTo-Xml Creates an XML-based representation of an object. Beginner Useful
Export-Alias Exports information about currently defined aliases to a file. Beginner Optional
Export-Clixml Creates an XML-based representation of an object or objects and stores it in a file. Beginner Useful
Export-Csv Converts objects into a series of comma-separated (CSV) strings and saves the strings in a CSV file. Beginner Mandatory
Format-Custom Uses a customized view to format the output. Advanced Useful
Format-List Formats the output as a list of properties in which each property appears on a new line. Beginner Useful
Format-Table Formats the output as a table. Beginner Useful
Format-Wide Formats objects as a wide table that displays only one property of each object. Beginner Useful
Get-Alias Gets the aliases for the current session. Beginner Useful
Get-Culture Gets the current culture set in the operating system. Beginner Useful
Get-Date Gets the current date and time. Beginner Mandatory
Get-Member Gets the properties and methods of objects. Beginner Mandatory
Get-Random Gets a random number, or selects objects randomly from a collection. Beginner Useful
Get-Unique Returns unique items from a sorted list. Beginner Useful
Get-Variable Gets the variables in the current console. Beginner Useful
Group-Object Groups objects that contain the same value for specified properties. Beginner Useful
Import-Clixml Imports a CLIXML file and creates corresponding objects within Windows PowerShell. Beginner Useful
Import-Csv Creates table-like custom objects from the items in a CSV file. Beginner Mandatory
Invoke-RestMethod Sends an HTTP or HTTPS request to a RESTful web service. Advanced Mandatory
Invoke-WebRequest Gets content from a web page on the Internet. Advanced Useful
Measure-Command Measures the time it takes to run script blocks and cmdlets. Beginner Useful
Measure-Object Calculates the numeric properties of objects, and the characters, words, and lines in string objects, such as files of text. Beginner Mandatory
New-Alias Creates a new alias. Beginner Optional
New-Object Creates an instance of a Microsoft .NET Framework or COM object. Beginner Mandatory
New-Variable Creates a new variable. Beginner Useful
Out-File Sends output to a file. Beginner Useful
Out-GridView Sends output to an interactive table in a separate window. Beginner Mandatory
Remove-Variable Deletes a variable and its value. Beginner Useful
Select-Object Selects objects or object properties. Beginner Mandatory
Select-String Finds text in strings and files. Beginner Optional
Select-Xml Finds text in an XML string or document. Advanced Optional
Set-Alias Creates or changes an alias (alternate name) for a cmdlet or other command element in the current Windows PowerShell session. Beginner Optional
Set-Variable Sets the value of a variable. Creates the variable if one with the requested name does not exist. Beginner Useful
Show-Command Creates Windows PowerShell commands in a graphical command window. Beginner Useful
Sort-Object Sorts objects by property values. Beginner Useful
Start-Sleep Suspends the activity in a script or session for the specified period of time. Beginner Useful
Write-Debug Writes a debug message to the console. Advanced Optional
Write-Error Writes an object to the error stream. Advanced Optional
Write-Output Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are displayed in the console. Advanced Optional
Write-Progress Displays a progress bar within a Windows PowerShell command window. Advanced Optional
Write-Verbose Writes text to the verbose message stream. Advanced Useful
Write-Warning Writes a warning message. Advanced Optional

Never use “write-host”
Use instead “write-verbose” see book recommended for more details.

Host Cmdlets

Cmdlet Description Level Importance
Start-Transcript Creates a record of all or part of a Windows PowerShell session to a text file. Beginner Optional
Stop-Transcript Stops a transcript. Beginner Optional

Management Cmdlets

Name Description Level Importance
Get-PSDrive Gets the Windows PowerShell drives in the current console. Advanced Useful
Get-PSProvider Gets information about the specified Windows PowerShell provider. Advanced Useful
New-PSDrive Creates a Windows PowerShell drive in the current console. Advanced Useful
Remove-PSDrive Removes a Windows PowerShell drive from its location. Advanced Useful
Test-Path Determines whether all elements of a path exist. Beginner Useful

Security Cmdlets

Name Description Level Importance
ConvertFrom-SecureString Converts a secure string into an encrypted standard string. Beginner Useful
ConvertTo-SecureString Converts encrypted standard strings to secure strings. It can also convert plain text to secure strings. It is used with ConvertFrom-SecureString and Read-Host. Beginner Useful
Get-Credential Gets a credential object based on a user name and password. Beginner Useful
Get-ExecutionPolicy Gets the execution policies in the current session. Beginner Useful
Set-ExecutionPolicy Changes the user preference for the execution policy of the shell. Beginner Useful

Advanced topics only

Advanced modules Level Importance
PSDesiredStateConfiguration Module Expert Optional
PSScheduledJob Module Advanced Useful
PSWorkflow Module Advanced Useful
PSWorkflowUtility Module Advanced Useful
CIM Cmdlets Advanced Useful

The CIM is related to access health of ESXi servers.

Reference Poster

PowerShell Basic Cheat Sheet 2
PowerShell Basic Cheat Sheet

Please note that these posters will cover areas not really needed for PowerCLI

Books recommended

Sams Teach Yourself Windows PowerShell in 24 Hours – May 2015
PowerShell in Depth, Second Edition – October 2014
I strongly recommend the second book even if it doesn’t cover latest version of PowerShell. It is really a deep dive.
Please note that these books will cover areas not really needed for PowerCLI

Finally an UFO
Access 2013 Bible – April 2013
Chapter 4 only linked to Data Normalization

Understanding database concepts are useful for PowerShell and this book introduce the Data Normalization concept in a nice way.
Understanding how to normalize data will help you to generate report in the logical way.
For example, even if it is possible to generate a report with one line per VM that contains disks and network adapters information (with one cell containing info of multiples disks for example), it will not be a report easy to export import or manipulate.
It will be difficult to identify quickly how many VM are connected to a specific network for example.
The reason is that a VM can have 0 to many disks and 0 to many network adapters.
It is just not possible to have them in “one” sheet (csv file, or excel) in a good way.
It is much better in that case to create one CSV file with VM Name, Disk size, Disk type etc with one line per disk.
And create another CSV file with VM Name, Network Adaper type, Network Name etc with one line per virtual network adapter.
Then you can for example import the two files in one excel file in two separate sheets,
It is also possible to export with XML to have everything in one file in a logical structure but XML is more challenging to manipulate

One thought on “PowerShell study guide – core concepts

  1. Pingback: PowerCLI study guide – core concepts - The Crazy Consultant

Leave a Reply

Your email address will not be published. Required fields are marked *