VMware Cloud Community
scriptermad
Enthusiast
Enthusiast
Jump to solution

Explanation for some commands

Hi

I am new to poewrcli and will be working a lot with it over the next while. Can someone explain the following lines to me please ? If someone could put comments beside each line to explain the syntax in its entirety then that would be great. This is not just one script, its a mix of different lines that i dont understand

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}    -------cell_id is an internal thing so ignore that

Write-host -ForegroundColor Green "Checking that Hosts are added by correct format"

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

$VMhostname =[string]$VMhostname

if (($VMhostname -eq $Esxihost) -or ($VMhostname -eq $Esxihostb))

Write-host -ForegroundColor Green $VMhostname Added Correctly

Write-host $Esxihost $Esxihostb

}

else

{

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

  {

$hostnameedit = $VMhostname.name.split(".")[0]

  $dsname = $hostnameedit + "-Local"

  Get-VMHost $VMhostname | Get-Datastore -Name * | Set-Datastore -Name $dsname

  Get-VirtualSwitch -VMHost $VMhostname | Get-NicTeamingPolicy | Set-NicTeamingPolicy -MakeNicActive vmnic1

  }

New-OSCustomizationSpec -Name $OSCostumSpec_VC -OSType Windows -AdminPassword $VMPassword  -TimeZone $TimeZone -ProductKey $WinProductKey_VC -ChangeSid -OrgName $OrgName -NamingScheme Fixed -NamingPrefix $VCVM.split(".")[0] -fullname Administrator -Workgroup WORKGROUP

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}

ForEach ($VMName in ($folder | Get-VM -name $VMMac)| where {$_.PowerState -eq "PoweredOff"} | sort)

{

Start-VM -VM $VMName -confirm:$false 

1 Solution

Accepted Solutions
RvdNieuwendijk
Leadership
Leadership
Jump to solution

PowerCLI and PowerShell commands can be read like English text. For example, the Get-Folder cmdlet retrieves one or more folders. Comment in a script can be started with the # sign. I will give comment to each line the first time it occurs.

# Retrieve a folder with name $cell.id and put it in the variable $folder. Could be written shorter as:

# $folder = Get-folder -Name $cell_id

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}    -------cell_id is an internal thing so ignore that

# Write a line to the console in green color.

Write-host -ForegroundColor Green "Checking that Hosts are added by correct format"

# Retrieve the ESXi hosts with name $VMHost in folder $folder, sort the hosts based on the names, and put them one for one # in the variable $VMHostName. In this example The $VMHostName variable contains VMHost objects and not the name of the # hosts.If you want to get the names, you should use:

# ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| Sort-Object | Select-Object -ExpandProperty Name)

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

# Make sure $VMHostName is a string by using the [string] typecast

$VMhostname =[string]$VMhostname

# Compare the $VMHostName with $Esxihost or $Esxihostb

if (($VMhostname -eq $Esxihost) -or ($VMhostname -eq $Esxihostb))

{

# Do this part if the result of the previous comparison is $true

Write-host -ForegroundColor Green $VMhostname Added Correctly

Write-host $Esxihost $Esxihostb

}

else

{

# Do this part if the result of the previous comparison is $false

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

  {

# Split the string in the $VMhostname variable at the dots and take the first piece.

$hostnameedit = $VMhostname.name.split(".")[0]

# Add two strings together

  $dsname = $hostnameedit + "-Local"

# Give a datastore a new name

  Get-VMHost $VMhostname | Get-Datastore -Name * | Set-Datastore -Name $dsname

# Set the NIC teaming policy and make vmnic1 the active NIC

  Get-VirtualSwitch -VMHost $VMhostname | Get-NicTeamingPolicy | Set-NicTeamingPolicy -MakeNicActive vmnic1

  }

# Create a new OSCustomizationSpec

New-OSCustomizationSpec -Name $OSCostumSpec_VC -OSType Windows -AdminPassword $VMPassword  -TimeZone $TimeZone -ProductKey $WinProductKey_VC -ChangeSid -OrgName $OrgName -NamingScheme Fixed -NamingPrefix $VCVM.split(".")[0] -fullname Administrator -Workgroup WORKGROUP

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}

# Retrieve the virtual machines that are powered of in folder $folder and sort them based on the names.

ForEach ($VMName in ($folder | Get-VM -name $VMMac)| where {$_.PowerState -eq "PoweredOff"} | sort)

{

# Start a virtual machine with name $VMName and don't ask for confirmation

Start-VM -VM $VMName -confirm:$false

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition

View solution in original post

0 Kudos
13 Replies
RvdNieuwendijk
Leadership
Leadership
Jump to solution

PowerCLI and PowerShell commands can be read like English text. For example, the Get-Folder cmdlet retrieves one or more folders. Comment in a script can be started with the # sign. I will give comment to each line the first time it occurs.

# Retrieve a folder with name $cell.id and put it in the variable $folder. Could be written shorter as:

# $folder = Get-folder -Name $cell_id

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}    -------cell_id is an internal thing so ignore that

# Write a line to the console in green color.

Write-host -ForegroundColor Green "Checking that Hosts are added by correct format"

# Retrieve the ESXi hosts with name $VMHost in folder $folder, sort the hosts based on the names, and put them one for one # in the variable $VMHostName. In this example The $VMHostName variable contains VMHost objects and not the name of the # hosts.If you want to get the names, you should use:

# ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| Sort-Object | Select-Object -ExpandProperty Name)

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

# Make sure $VMHostName is a string by using the [string] typecast

$VMhostname =[string]$VMhostname

# Compare the $VMHostName with $Esxihost or $Esxihostb

if (($VMhostname -eq $Esxihost) -or ($VMhostname -eq $Esxihostb))

{

# Do this part if the result of the previous comparison is $true

Write-host -ForegroundColor Green $VMhostname Added Correctly

Write-host $Esxihost $Esxihostb

}

else

{

# Do this part if the result of the previous comparison is $false

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

  {

# Split the string in the $VMhostname variable at the dots and take the first piece.

$hostnameedit = $VMhostname.name.split(".")[0]

# Add two strings together

  $dsname = $hostnameedit + "-Local"

# Give a datastore a new name

  Get-VMHost $VMhostname | Get-Datastore -Name * | Set-Datastore -Name $dsname

# Set the NIC teaming policy and make vmnic1 the active NIC

  Get-VirtualSwitch -VMHost $VMhostname | Get-NicTeamingPolicy | Set-NicTeamingPolicy -MakeNicActive vmnic1

  }

# Create a new OSCustomizationSpec

New-OSCustomizationSpec -Name $OSCostumSpec_VC -OSType Windows -AdminPassword $VMPassword  -TimeZone $TimeZone -ProductKey $WinProductKey_VC -ChangeSid -OrgName $OrgName -NamingScheme Fixed -NamingPrefix $VCVM.split(".")[0] -fullname Administrator -Workgroup WORKGROUP

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}

# Retrieve the virtual machines that are powered of in folder $folder and sort them based on the names.

ForEach ($VMName in ($folder | Get-VM -name $VMMac)| where {$_.PowerState -eq "PoweredOff"} | sort)

{

# Start a virtual machine with name $VMName and don't ask for confirmation

Start-VM -VM $VMName -confirm:$false

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
scriptermad
Enthusiast
Enthusiast
Jump to solution

Ok thanks for the help.

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}


Lets same that cell_id is declared at the start of the script as $cell_id=20


so the line means basically, get what ever value thats in the cell id , in this case 20 and put it in a variable called folder ?


Im stuggling with this part below ....

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)   ---- to me, this means look in the folder $folder, get the hostnames and sort

What is $vmhostname ? I dont see that parameter declared at the start of the script.

What is $vmhost ? At the beginning of the script, this line exists

$vmhost='*'

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

$folder = Get-folder $folderName | where {$_.name -eq $cell_id}


Lets same that cell_id is declared at the start of the script as $cell_id=20


so the line means basically, get what ever value thats in the cell id , in this case 20 and put it in a variable called folder ?


--> Not exactly. After executing the command, the $folder variable will contain a PowerCLI folder object, for a folder with name 20.


Im stuggling with this part below ....

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)   ---- to me, this means look in the folder $folder, get the hostnames and sort

What is $vmhostname ? I dont see that parameter declared at the start of the script.

--> In PowerShell you don't have to declare a variable before you use the variable. In this case $VMHostName is a variable that will contain the current ESXi host object, for every time the foreach loop is processed, .

What is $vmhost ? At the beginning of the script, this line exists

$vmhost='*'

--> The * symbol is a wildcard. So, if you use Get-VMHost -Name $vmhost, you will retrieve all ESXi host objects.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
scriptermad
Enthusiast
Enthusiast
Jump to solution

I still dont get ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)   -   if all this is doing is getting the hostnames then why the $vmshostname ?

Also what part of the syntax puts the hostnames into $vmhostname ? I dont undrstand how $vmhostname will contain the current host object

0 Kudos
naiksidd
Enthusiast
Enthusiast
Jump to solution

let me make it simple,

say you have a class of 10 students,

every student has name, age and roll number.

Student 1 name = abc

Student 1 age = 20

Student 1 roll number = 1

Student 2 name = pqr

Student 2 age = 20

Student 2 roll number = 2

and so on ...

all the 3 properties are saved as 1 entry for every student, now there are 10 entries with each entry having 3 properties.

all 10 entries are saved in 1 array called StudentsArray.

so StudentsArray[0] is entry of 1st student

better way of writing this is

foreach($student in $StudentsArray)

{ $StudentName = $student.Name}

or you can also write

for($i = 0; $i -lt 10, $i++)

{

      $StudentName = StudentsArray[$i].Name

}

0 Kudos
scriptermad
Enthusiast
Enthusiast
Jump to solution

so $vmhostname is an array as opposed to a variable ?

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

In " ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort) " $VMhostname will contain a single object, and not an array. It is the current object in the foreach loop.

I will give another example. First I will create an array containing the integers 1,2, and 3. Then I will use the foreach command to loop through all of the array elements and multiple the current element with 2. The foreach command runs the code in the scriptblock, between {}, for each element in the array.

PowerCLI C:> $Array = 1,2,3

PowerCLI C:> foreach ($Element in $Array) {$Element*2}


The previous commands will give the following output:

2

4

6

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
naiksidd
Enthusiast
Enthusiast
Jump to solution

$vmHostName is variable.. that holds this entry

0 Kudos
scriptermad
Enthusiast
Enthusiast
Jump to solution

ok im getting there but in your example above, how does $element become each entry in the array.

I mean, if the array holds 1,2,3 , how does just creating $element mean that $element become the array contents ?

OR could $element be called anything, and the syntax ($variable in $Array) is what does the actual job ?

And in your example  --- ($Element in $Array) {$Element*2}   - what is the difference between () and {}

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

The difference between () and {} is that () is an expression and {} a scriptblock.

If you remember from school:

2*3+4 = 10 and 2*(3+4) = 14

In the first example, 2*3 is evaluated first. In the second example, 3+4 is evaluated first, because of the ().

You can use the () in PowerShell and PowerCLI just like in the second example. It means that what is between () should be evaluated before the rest of the command.

A scriptblock contains a piece of PowerShell code.

You can get the foreach command help with:

PowerCLI C:> Get-Help about_foreach

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
naiksidd
Enthusiast
Enthusiast
Jump to solution

No offence to any one, but

I think these are more of Powershell and Programming questions than Powercli questions.

0 Kudos
scriptermad
Enthusiast
Enthusiast
Jump to solution

ok and in the line  $folder = Get-folder $folderName | where {$_.name -eq $cell_id}     ---- the result / output is put in $folder. What is the purpose of $foldername then ?

should it not just be $folder = Get-folder  | where {$_.name -eq $cell_id}

and for the line below - i understand that $vmhostname is the variable for what ever is in $folder, this is then piped and get-vmhost lists the host names but what then is hte purpose of $VMhost??

ForEach ($VMhostname in ($folder | Get-VMHost -name $VMhost)| sort)

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

In "$folder = Get-folder $folderName | where {$_.name -eq $cell_id}", $foldername does not make much sense. You can better use:

$folder = Get-folder -Name $cell_id


In the second question, you can use $VMHost to filter for hosts with a certain name in the folder. However, if $VMHost contains '*', it does not have a purpose, because retrieving all of the hosts in the folder is the default.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition