VMware Cloud Community
mars0077
Enthusiast
Enthusiast
Jump to solution

Invoke-VMScript to basically select the correct Guest OS powershell script as part of the execution.

Hello friends,

I have been working on an script that basically clones a virtual machine and reconfigures the new virtual machines according to the variables that I have specified. All of this is working as expected. The area that I am having trouble with is using the Invoke-VMScript function to call a specific powershell script that only applies to the new VM.

What I would like to do is rely on the Invoke-VMScript to basically select the appropriate Guest OS powershell script as part of the execution. For example, inside the cloned VM there are powershell scripts for 3 VM's that basically rename and re-IP the VM according to its VM name.

What I would like to accomplish here, is clone the VM and either be able to specify the corresponding guest OS script via variable or be prompted to enter the location for its corresponding script. See workflow below:

Workflow:

Source VM ---> Cloned VM1 ---> Invoke-VMScript poweshell script that would apply to VM1 inside the OS = This Guest OS poweshell script renames the cloned OS to the same VM1 name and provides its IP.

Source VM ---> Cloned VM2 ---> Invoke-VMScript poweshell script that would apply to VM2 inside the OS = This Guest OS poweshell script renames the cloned OS to the same VM2 name and provides its IP.

Source VM ---> Cloned VM3 ---> Invoke-VMScript poweshell script that would apply to VM3 inside the OS = This Guest OS poweshell script renames the cloned OS to the same VM3 name and provides its IP.

Part of my script prompts the user to enter the name of the new clone. I then use this as a variable to create the new clone. It would be awesome if I could also use this to automatically execute the correct Guest OS powershell script based on the name that I am using.

Script:

##Variables to be used for constructing the VM

$Datastorecls = "VMFSCLS-01"

$ESXCLS = "ESXCLS"

$Folder = "POC"

$Network = "DMZ"

$SourceVM = "POCVM"

$NewDemoInstance = Read-host "Enter the name of the VM you wish to create"

##Script that will clone the VM

New-VM -Name $NewDemoInstance -VM $SourceVM -Location $Folder -Datastore $Datastorecls -ResourcePool $ESXCLS | Get-NetworkAdapter | Where {$_.NetworkName -eq "PROD"} | Set-NetworkAdapter -NetworkName $Network -Confirm:$false

Get-VM $NewDemoInstance | Where-Object {$_.PowerState -eq "PoweredOff"} | Start-VM

sleep 120

##Script that will reconfigure the interface for DHCP, remove any static routes and configure the new IP

Invoke-VMScript -VM $NewDemoInstance -GuestUser Admin -GuestPassword '******' -ScriptText c:\Scripts\SetIP_Name_POC.ps1 -Confirm:$false  ---> Here's where I would like either a variable or a prompt.

Thanks so much guys!!

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The New-VM needs to be moved after the selection.

Something like this.
PS: you will probably need to use the ScriptType parameter as well on the Invoke-VMScript cmdlet.

##Variables to be used for constructing the VM

$Datastorecls = "VMFSCLS-01"

$ESXCLS = "ESXCLS"

$Folder = "POC"

$Network = "DMZ"

$SourceVM = "POCVM"

##Script to execute based on user input

$answer = 0

Write-Host "1. POCVM1"

Write-Host "2. POCVM2"

Write-Host "3. POCVM3"

while(1,2,3 -notcontains $answer){

    $answer = Read-host "Enter the type of script you wish to execute"

}

if($answer -eq 1){

    $NewDemoInstance = 'POCVM1'

    $scriptName = 'POCVM1.ps1'

}

if($answer -eq 2){

    $NewDemoInstance = 'POCVM2'

    $scriptName = 'POCVM2.ps1'

}

if($answer -eq 3){

    $NewDemoInstance = 'POCVM3'

    $scriptName = 'POCVM3.ps1'

}

##Script that will clone the VM

New-VM -Name $NewDemoInstance -VM $SourceVM -Location $Folder -Datastore $Datastorecls -ResourcePool $ESXCLS |

Get-NetworkAdapter | Where {$_.NetworkName -eq "PROD"} |

Set-NetworkAdapter -NetworkName $Network -Confirm:$false

Get-VM $NewDemoInstance | Where-Object {$_.PowerState -eq "PoweredOff"} | Start-VM

sleep 120

Invoke-VMScript -VM $NewDemoInstance -GuestUser Admin -GuestPassword '******' -ScriptText "C:\Scripts\$scriptName" -Confirm:$false


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

Not sure I'm following 100%, but my interpretation:

  • Your $SourceVM contains 3 scripts (.ps1 files)
  • From your $SourceVM you can clone 3 types of VMs
  • Depending on which type of clone you selected, you want to run 1 of the 3 scripts in the guestOS

If my assumption is correct, can't you do something along these lines in that case?

$answer = 0

Write-Host "1 Clone type A"

Write-Host "2 Clone type B"

Write-Host "3 Clone type C"

while(1,2,3 -notcontains $answer){

    $answer = Read-host "Enter the type of close you wish to create"

}

if($answer -eq 1){

    $NewDemoInstance = 'AAA'

    $scriptName = 'a.ps1'

}

if($answer -eq 2){

    $NewDemoInstance = 'BBB'

    $scriptName = 'b.ps1'

}

if($answer -eq 3){

    $NewDemoInstance = 'CCC'

    $scriptName = 'c.ps1'

}

Invoke-VMScript -VM $NewDemoInstance -GuestUser Admin -GuestPassword '******' -ScriptText "C:\Scripts\$scriptName" -Confirm:$false


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mars0077
Enthusiast
Enthusiast
Jump to solution

Thanks Luc!! I think your code will do the job, but I'm a bit confused as to where I should I include your code snipped? Would it go at the bottom?

Here's the whole script:

##Variables to be used for constructing the VM

$Datastorecls = "VMFSCLS-01"

$ESXCLS = "ESXCLS"

$Folder = "POC"

$Network = "DMZ"

$SourceVM = "POCVM"

$NewDemoInstance = Read-host "Enter the name of the VM you wish to create"

##Script that will clone the VM

New-VM -Name $NewDemoInstance -VM $SourceVM -Location $Folder -Datastore $Datastorecls -ResourcePool $ESXCLS | Get-NetworkAdapter | Where {$_.NetworkName -eq "PROD"} | Set-NetworkAdapter -NetworkName $Network -Confirm:$false

Get-VM $NewDemoInstance | Where-Object {$_.PowerState -eq "PoweredOff"} | Start-VM

sleep 120

##Script to execute based on user input

$answer = 0

Write-Host "POCVM1"

Write-Host "POCVM2"

Write-Host "POCVM3"

while(1,2,3 -notcontains $answer){

    $answer = Read-host "Enter the type of script you wish to execute"

}

if($answer -eq 1){

    $NewDemoInstance = 'POCVM1'

    $scriptName = 'POCVM1.ps1'

}

if($answer -eq 2){

    $NewDemoInstance = 'POCVM2'

$scriptName = 'POCVM2.ps1'

}

if($answer -eq 3){

    $NewDemoInstance = 'POCVM3'

    $scriptName = 'POCVM3.ps1'

}

Invoke-VMScript -VM $NewDemoInstance -GuestUser Admin -GuestPassword '******' -ScriptText "C:\Scripts\$scriptName" -Confirm:$false

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The New-VM needs to be moved after the selection.

Something like this.
PS: you will probably need to use the ScriptType parameter as well on the Invoke-VMScript cmdlet.

##Variables to be used for constructing the VM

$Datastorecls = "VMFSCLS-01"

$ESXCLS = "ESXCLS"

$Folder = "POC"

$Network = "DMZ"

$SourceVM = "POCVM"

##Script to execute based on user input

$answer = 0

Write-Host "1. POCVM1"

Write-Host "2. POCVM2"

Write-Host "3. POCVM3"

while(1,2,3 -notcontains $answer){

    $answer = Read-host "Enter the type of script you wish to execute"

}

if($answer -eq 1){

    $NewDemoInstance = 'POCVM1'

    $scriptName = 'POCVM1.ps1'

}

if($answer -eq 2){

    $NewDemoInstance = 'POCVM2'

    $scriptName = 'POCVM2.ps1'

}

if($answer -eq 3){

    $NewDemoInstance = 'POCVM3'

    $scriptName = 'POCVM3.ps1'

}

##Script that will clone the VM

New-VM -Name $NewDemoInstance -VM $SourceVM -Location $Folder -Datastore $Datastorecls -ResourcePool $ESXCLS |

Get-NetworkAdapter | Where {$_.NetworkName -eq "PROD"} |

Set-NetworkAdapter -NetworkName $Network -Confirm:$false

Get-VM $NewDemoInstance | Where-Object {$_.PowerState -eq "PoweredOff"} | Start-VM

sleep 120

Invoke-VMScript -VM $NewDemoInstance -GuestUser Admin -GuestPassword '******' -ScriptText "C:\Scripts\$scriptName" -Confirm:$false


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mars0077
Enthusiast
Enthusiast
Jump to solution

Awesome sir!! I will try it and will let you know how things go. Much appreciated and thanks again.

0 Kudos
mars0077
Enthusiast
Enthusiast
Jump to solution

Thanks again Luc! Your code was dead on spot!!

0 Kudos
mars0077
Enthusiast
Enthusiast
Jump to solution

Mr. Luc,

Need your help again on this one. Is there a way I can have the script ignore the user input if the VM they were supposed to delete is no longer there? In other words, if the VM is no longer present, how can I ignore the code below and continue with the VM creation that comes next?

Code:

##Delete VM

Get-VM *sls*

$DemoInstance = Read-Host "Enter the name of the VM you wish to delete"

##Script to delete VM

Get-VM $DemoInstance | Where-Object {$_.PowerState -eq "PoweredOn"} | Stop-VM -Confirm:$false

Remove-VM $DemoInstance -DeletePermanently -Confirm:$false

##VM Creation

##Variables and user input to be used for constructing the demo VM##

$Datastorecls = "VMFSCLS-01"

$ESXCLS = "ESXCLS"

$Folder = "Sls"

$Network = "Network"

$SourceVM = "POC"

$NewDemoInstance = Read-host "Enter the name of the VM you wish to create"

Much appreciated sir!!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do something like this

##Delete VM

Get-VM *sls*

$DemoInstance = Read-Host "Enter the name of the VM you wish to delete"

##Script to delete VM

$vm = Get-VM $DemoInstance -ErrorAction SilentlyContinue

if($vm){

    $vm | Where-Object {$_.PowerState -eq "PoweredOn"} | Stop-VM -Confirm:$false

    Remove-VM -VM $vm -DeletePermanently -Confirm:$false

}

else{

    Write-Host "Can't find VM $DemoInstance"

    return

}

##VM Creation

##Variables and user input to be used for constructing the demo VM##

$Datastorecls = "VMFSCLS-01"

$ESXCLS = "ESXCLS"

$Folder = "Sls"

$Network = "Network"

$SourceVM = "POC"

$NewDemoInstance = Read-host "Enter the name of the VM you wish to create"


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mars0077
Enthusiast
Enthusiast
Jump to solution

Thanks again for your help sir. I tried using the code you provided and here's the output.

Enter the name of the VM you wish to delete: sls

Can't find VM sls

After this, the script halts and does not continue with the VM creation. How can I get the script to keep going?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Just remove the line with return on it.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mars0077
Enthusiast
Enthusiast
Jump to solution

Thank you very much sir!! It worked perfectly,.

0 Kudos