Vel_VMware
Enthusiast
Enthusiast

Snapshot script

I am trying to write script to create and delete snapshot for VM's list which is for different vCenter. I have CSV file which has VMs name and respective vCenter name in another column.

Its asking for credential for connecting each vCenter.

For creating snapshot:

$Data = Import-CSV -Path 'T:\VMs.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Cre = Get-Credential -Message "Enter Credential"

foreach($VC in $VCServer) {

try{

   

     $VC = Connect-VIServer -Server $VCServer -Credential $Cre -ErrorAction Stop

}

catch {

     throw "Connection to $Server failed!"

      }

     foreach($VM in Get-VM $VmHost | Select Name) {

    $Date = Get-Date -Format 'yyyyMMdd'

    New-Snapshot -VM $vm -Name "$vm_BeforeUpdate_$Date" -description 'Upgrade'

}

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

For deleting snapshot:

$Data = Import-CSV -Path 'T:\VMs.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Cre = Get-Credential -Message "Enter Credential"

foreach($VC in $VCServer) {

try{

   

     $VC = Connect-VIServer -Server $VCServer -Credential $Cre -ErrorAction Stop

}

catch {

     throw "Connection to $Server failed!"

      }

     foreach($VM in Get-VM $VmHost | Select Name) {

     Get-VM -Name $vm | Get-Snapshot | Remove-Snapshot

}

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

23 Replies
LucD
Leadership
Leadership

If you run this from a Windows box, you could use the New-VICredentialStoreItem cmdlet to store the credentials.

Then you can connect to each vCenter without specifying credentials.

More info in Have you seen PowerCLI’s “Credential Store” feature?


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

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

I changed like below,

$Data = Import-CSV -Path 'T:\Script\Snapshot_Script\HCXComponents.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Username = Read-Host  -Prompt 'Username'

$Password = Read-Host  -Prompt 'Password' -AsSecureString

#$Cre = Get-Credential -Message "Enter Credential"

foreach($VC in $VCServer) {

try{

   

    New-VICredentialStoreItem -Host $VCServer -User $Username -Password $Password    

}

catch {

    throw "Connection to $Server failed!"

    }

   

    foreach($VM in Get-VM $VmHost | Select Name) {

    $Date = Get-Date -Format 'yyyyMMdd'

    New-Snapshot -VM $vm -Name "$vm_BeforeUpdate_$Date" -description 'Upgrade'

}

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

I changed like below,

$Data = Import-CSV -Path 'T:\Script\Snapshot_Script\HCXComponents.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Username = Read-Host  -Prompt 'Username'

$Password = Read-Host  -Prompt 'Password' -AsSecureString

#$Cre = Get-Credential -Message "Enter Credential"

foreach($VC in $VCServer) {

try{

   

    New-VICredentialStoreItem -Host $VCServer -User $Username -Password $Password    

}

catch {

    throw "Connection to $Server failed!"

    }

   

    foreach($VM in Get-VM $VmHost | Select Name) {

    $Date = Get-Date -Format 'yyyyMMdd'

    New-Snapshot -VM $vm -Name "$vm_BeforeUpdate_$Date" -description 'Upgrade'

}

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

I changed like below,

$Data = Import-CSV -Path 'T:\Script\Snapshot_Script\HCXComponents.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Username = Read-Host  -Prompt 'Username'

$Password = Read-Host  -Prompt 'Password' -AsSecureString

#$Cre = Get-Credential -Message "Enter Credential"

foreach($VC in $VCServer) {

try{

   

    New-VICredentialStoreItem -Host $VCServer -User $Username -Password $Password    

}

catch {

    throw "Connection to $Server failed!"

    }

   

    foreach($VM in Get-VM $VmHost | Select Name) {

    $Date = Get-Date -Format 'yyyyMMdd'

    New-Snapshot -VM $vm -Name "$vm_BeforeUpdate_$Date" -description 'Upgrade'

}

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Sorry unknowingly it came three time in thread.

I am getting error like below,

Get-VM : 04-03-2020 12:23:28    Get-VM        You are not currently connected to any servers. Please connect first

using a Connect cmdlet.

At T:\Script\Snapshot_Script\Snapshot_Creation.ps1:26 char:20

+     foreach($VM in Get-VM $VmHost | Select Name) {

+                    ~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (:) [Get-VM], ViServerConnectionException

    + FullyQualifiedErrorId : Core_BaseCmdlet_NotConnectedError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Also after the above error still its asking for credential to connect another vCeter.. Can you help me by modifying the script please.

0 Kudos
LucD
Leadership
Leadership

Did you look at the New-VICredentialStoreItem cmdlet I suggested?

That error seems to indicate you are not connected to a vCenter when you run the Get-VM.


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

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Yes I did, by referring that only I changed my script which I have posted.

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Ok, Now no errors, But still asking for credential when connecting another vCenter.

$Data = Import-CSV -Path 'T:\VMs.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Username = Read-Host  -Prompt 'Username'

$Password = Read-Host  -Prompt 'Password' -AsSecureString

     

    foreach($VC in $VCServer) {

    New-VICredentialStoreItem -Host $VC -User $Username -Password $Password   

    try{

   

     Connect-VIServer $VC

    }

    catch {

    throw "Connection to $Server failed!"

    }

   

    $vms = Get-VM $VmHost

    foreach($VM in $vms) {

    $Date = Get-Date -Format 'yyyyMMdd'

    New-Snapshot -VM $VmHost -Name "$vm_BeforeUpdate_$Date" -description 'Upgrade'

}

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

0 Kudos
LucD
Leadership
Leadership

You have to create the entry with New-VICredentialSToreItem before running your script.

Not inside your script.

Did you read the blog post I referred to earlier?


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

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Yes I read it fully and applied  the same, can you check below script  and can you change it if anything wrong.

Data = Import-CSV -Path 'T:\VMs.csv' -delimiter “;”

$Data | foreach {

$VmHost = $_.ApplianceName

$VCServer = $_.vCenterServer

$Username = Read-Host  -Prompt 'Username'

$Password = Read-Host  -Prompt 'Password' -AsSecureString

New-VICredentialStoreItem -Host $VC -User $Username -Password $Password 

    $vms = Get-VM $VmHost

    foreach($VM in $vms) {

    try{  

     Connect-VIServer $VC

    }

    catch {

    throw "Connection to $Server failed!"

    }

    $Date = Get-Date -Format 'yyyyMMdd'

    New-Snapshot -VM $VmHost -Name "$vm_BeforeUpdate_$Date" -description 'Upgrade'

}

}

Disconnect-VIServer -Server $VC -Confirm:$false

0 Kudos
LucD
Leadership
Leadership

You first need to create the VICredentialStoreItem entries, one for each vCenter in your CSV.

With something like this

Import-CSV -Path 'T:\VMs.csv' -delimiter “;|

select -ExpandProperty vCenterServer |

Sort-Object -Unique |

ForEach-Object -Process {

    $user = Read-Host -Prompt "User for $($_.vCenterServer)"

    $secPswd = Read-Host -Prompt "password for $($_.vCenterServer)" -AsSecureString

    $pswd = (New-Object PSCredential "user",$secPswd).GetNetworkCredential().Password

    New-VICredentialStoreItem -Host $_.vCenterServer -User $user -Password $pswd

}

Now you can run your Connect-VIServer without a User and Password.

Your snapshot script could now be something like this.

$Date = Get-Date -Format 'yyyyMMdd'

$Data = Import-CSV -Path 'T:\VMs.csv' -delimiter “;

$Data | ForEach-Object -Process {

    try{

        Connect-VIServer -Server $_.vCenterServer

    }

    catch {

        throw "Connection to $Server failed!"

    }


    Get-VM -Name $_.ApplianceName |

    New-Snapshot -Name "$vm_BeforeUpdate_$Date" -Description 'Upgrade'

    Disconnect-VIServer -Server $VC -Confirm:$false

}


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

Vel_VMware
Enthusiast
Enthusiast

I ran the script and getting below error, Then its asking for user credential again.

User for : test@vsphere.local

password for : ********

New-VICredentialStoreItem : Cannot validate argument on parameter 'Host'. The argument is null or empty. Provide an

argument that is not null or empty, and then try the command again.

At T:\Script\Snapshot_Script\Snapshot_Creation.ps1:11 char:37

+     New-VICredentialStoreItem -Host $_.vCenterServer -User $user -Password $pswd

+                                     ~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [New-VICredentialStoreItem], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVICrede

   ntialStoreItem

User for :

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Ok just give me some time.. I missed to change something in the code..

Let me change it and check, then will come back to you.

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Still I am getting the same error.

0 Kudos
LucD
Leadership
Leadership

That seems to imply that there might be an issue with your CSV file.
Or the column is not named vCenterServer, or there are 1 or more empty lines in the CSV.

If you do Get-VICredentialStoreItem, does it return anything?


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

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Its returns my credential.. I think script is not taking vCenter name and checked the CSV file as well. I don't check anything working in it.

The columns are,

ApplianceName;vCenterServer

0 Kudos
LucD
Leadership
Leadership

Does this return all your vCenter names?

Import-CSV -Path 'T:\VMs.csv' -delimiter “;|

select -ExpandProperty vCenterServer |

Sort-Object -Unique


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

0 Kudos
Vel_VMware
Enthusiast
Enthusiast

Yes, it returns. Also, I tried to change the code like below and it works somehow. But, its looping and script is not ending. Its again asking for credential and creating second snapshot once script ends with complete list of VM's in CSV.

$Data = Import-CSV -Path 'T:\Script\Snapshot_Script\HCXComponents.csv' -delimiter “;” $Data | foreach {

$VCServer = $_.vCenterServer

#select -ExpandProperty vCenterServer |

#Sort-Object -Unique |

ForEach-Object -Process {

    $user = Read-Host -Prompt "User for $VCServer "

    $secPswd = Read-Host -Prompt "password for $VCServer " -AsSecureString

    $pswd = (New-Object PSCredential "user",$secPswd).GetNetworkCredential().Password

    New-VICredentialStoreItem -Host $VCServer  -User $user -Password $pswd

}

$Date = Get-Date -Format 'yyyyMMdd'

$Data = Import-CSV -Path 'T:\Script\Snapshot_Script\HCXComponents.csv' -delimiter “;”

$Data | ForEach-Object -Process {

    try{

        Connect-VIServer -Server $_.vCenterServer

    }

    catch {

       throw "Connection to $VCServer failed!"

    }

    Get-VM -Name $_.ApplianceName |

    New-Snapshot -Name "$vm_BeforeUpdate_$Date" -Description 'Upgrade'

    Disconnect-VIServer -Confirm:$false

}

}

0 Kudos
LucD
Leadership
Leadership

This thread is again becoming one long debug session.

I'm afraid I can't really help you any further if you don't provide more details in your answers.

If the above is indeed returning all your vCenters then I don't understand why Get-VICredentialStoreItem doesn't return anything.


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

0 Kudos