Automation

 View Only
Expand all | Collapse all

Create Snapshot based on CSV files

Sabri CHARCHOUF

Sabri CHARCHOUFJan 25, 2023 02:10 PM

LucD

LucDJan 25, 2023 02:50 PM

Sabri CHARCHOUF

Sabri CHARCHOUFJan 25, 2023 08:05 PM

  • 1.  Create Snapshot based on CSV files

    Posted Jan 24, 2023 03:34 PM

    Hello,

    for some requirement we need always to have LOGs for scripts that we are running

    I have the below script that is supposed to create snapshots based on CSV files, unfortunately no snapshots taken and no error message

     

    The idea of the script is that once Snapshots are created later we will remove them based on their name and snapshot description details

     

     

     

    #---------------------------------------------------------[Initialisations]--------------------------------------------------------
    [console]::BackgroundColor = "Black"
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls, [System.Net.SecurityProtocolType]::Tls11, [System.Net.SecurityProtocolType]::Tls12
    Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
    Clear-Host
    
    # Set debug action to continue if you want debug messages at console
    $DebugPreference = "SilentlyContinue"
    
    # Get filename of script and use the same name for the logfile without file extension
    $ScriptName = $MyInvocation.MyCommand.Name
    $ScriptName = $ScriptName.Replace(".ps1","")
    #Get date today for logfile in format day-month-year_hours-minutes, e.g. 24-11-2015_19-30
    $Today = get-date -format d-M-yyyy_HH-mm
    Add-Type -AssemblyName System.Windows.Forms
    
    $StartTime = Get-Date    
    #----------------------------------------------------------[Declarations]----------------------------------------------------------
    # Define log file
    $FilePath = ".\LOGs-Output"
    $ScriptLOG = "$($ScriptName)_$($Today).log"
    $LogFile = Join-Path -Path $FilePath -ChildPath $ScriptLOG
    #---------------------------------------------------------[Function Write-Log]------------------------------------------------------
    function Write-Log {
        [CmdletBinding()]
        Param
        (      
            [Parameter(Mandatory = $true)]
            [string] $FilePath,
    
            [Parameter(Mandatory = $true)]
            [string] $Message,
    
            [ValidateSet("Info", "Warning", "Error", "Success", "Control")]
            $Level = "Info",
    
            [switch]$Clear,
    
            [switch]$StartInfo,
    
            [switch]$StartControl
        )
    
        if (Test-Path -Path (Split-Path -Path $FilePath -Parent)) {
            $FormattedDate = Get-Date -Format "[yyyy-MM-dd][HH:mm:ss]"
            $OutString = "$FormattedDate - $Level - Folder Exists"
            $OutString | Out-File -FilePath $FilePath -Append
          }
          else {
            New-Item -Path '.\LOGs-Output' -ItemType Directory
            $FormattedDate = Get-Date -Format "[yyyy-MM-dd][HH:mm:ss]"
            $OutString = "$FormattedDate - $Level - Folder Created"
            $OutString | Out-File -FilePath $FilePath
        }
    
        if ($Clear) {
            Clear-Content -Path $FilePath
        }
    
        if ($StartInfo) {
            [string[]]$StartText = @()
            $StartText += "$("#" * 100)"
            $StartText += "# Running script : $($MyInvocation.ScriptName)"
            $StartText += "# Start time : $(Get-Date)"  
            $StartText += "# Executing account : $([Security.Principal.WindowsIdentity]::GetCurrent().Name)"
            $StartText += "# ComputerName : $env:COMPUTERNAME"
            $StartText += "$("#" * 100)"
            $StartText | Out-File -FilePath $FilePath -Append
        }
    
        $FormattedDate = Get-Date -Format "[yyyy-MM-dd][HH:mm:ss]"
        $OutString = "$FormattedDate - $Level - $Message"
        $OutString | Out-File -FilePath $FilePath -Append
    
        switch ($Level) {
            "Info" { Write-Host $OutString -ForegroundColor Gray ; break }
            "Warning" { Write-Host $OutString -ForegroundColor Yellow; break }
            "Error" { Write-Host $OutString -ForegroundColor Red; break }
            "Success" { Write-Host $OutString -ForegroundColor Green; break }
            "Control" { Write-Host $OutString -ForegroundColor Cyan; break }
            Default { Write-Host $OutString; break }
        }
       
    }
    #-----------------------------------------------------------------------------------------------------------------------------------
    Write-Log -FilePath $LogFile -Message "Script started by $([Environment]::UserName) on $([Environment]::MachineName)" -StartInfo
    ######################################
    if (Get-Module -ListAvailable -Name VMware.PowerCLI) {
        Write-Log -FilePath $LogFile -Message "[+] PowerCLI module exists`n" -Level Success
    }
    else {
        Write-Log $FilePath $LogFile -Message "[-] Module does not exist. PowerCLI installation..." -Level Warning
        Install-Module -Name VMware.PowerCLI -Force
        Set-PowerCLIConfiguration -InvalidCertificateAction:Ignore
    }
    Import-Csv -Delimiter ";" -Path ".\VM_List\VMs.csv" |
        ForEach-Object -Process {
      Get-VM -Name $_.VMName | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Confirm:$false
    }

     



  • 2.  RE: Create Snapshot based on CSV files

    Posted Jan 24, 2023 05:16 PM

    Are snapshots created when you just do this?

    Import-Csv -Delimiter ";" -Path ".\VM_List\VMs.csv" |
        ForEach-Object -Process {
      Get-VM -Name $_.VMName | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Confirm:$false
    }


  • 3.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 10:18 AM

    Hello

    In VMs.csv I have 2 VMs and I got the below error message

    lElOUCHE_79_0-1674641876007.png

     



  • 4.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 10:25 AM

    Do you have an empty line in the CSV?
    What exactly is in the CSV?



  • 5.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 11:20 AM

    no empty line in the CSV

    in the CSV file I have

    VM_1;

    VM_2;



  • 6.  RE: Create Snapshot based on CSV files
    Best Answer

    Posted Jan 25, 2023 11:41 AM

    On the 1st row you should have the name of the column.
    No need for a separator when the CSV only has 1 column

     

    VMName
    VM_1
    VM_2

     



  • 7.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 12:14 PM

    Thank you it's working fine

    lElOUCHE_79_0-1674648746716.png

    One of the VM is Powerd ON, unfortunately, I got the PowerState for both as PowerdOFF

     

    It's a normal behavior?



  • 8.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 01:06 PM

    No, that is not normal.
    When the VM is powered on, the Get-VM (or New-Snapshot) should not show it as powered off.

    Does a Get-VM show it as powered on?



  • 9.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 02:10 PM

    Get-VM show it as powerd on

    strange



  • 10.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 02:19 PM

    I just did some tests, and indeed the I also see the PoweredOff state, although the VM is powered on.
    Seems to powerstate that is shown on the output of New-Snapshot, indicates the state of the Memory switch.

    Without the -Memory switch, the output of New-Snapshot always shows "poweredoff".
    With the -Memory switch present, powerstate shows "poweredon" when the VM was powered on during the snapshot, and "poweredoff" when the VM was powered off.

    A bit confusing



  • 11.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 02:45 PM

    Ah ! Ok then I should add -Memory switch, I made some search but not able to find how I can solve this

    https://vdc-repo.vmware.com/vmwb-repository/dcr-public/85a74cac-7b7b-45b0-b850-00ca08d1f238/ae65ebd9-158b-4f31-aa9c-4bbdc724cc38/doc/New-Snapshot.html

     



  • 12.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 02:50 PM

    See Example 2 on that page



  • 13.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 03:10 PM

    Ah Ok , then I should add

    -Memory $false

    Because I will not Snapshot the virtual machine's memory  

    And I should have something like this :

     

     

    Import-Csv -Delimiter ";" -Path ".\VM_List\VMs.csv" |
        ForEach-Object -Process {
      Get-VM -Name $_.VMName -Memory $false | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Confirm:$false
    }

     

     



  • 14.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 05:15 PM

    That -Memory parameter goes on the New-Snapshot cmdlet.
    But setting it to $false will show the VM as being powered off in the snapshot.



  • 15.  RE: Create Snapshot based on CSV files

    Posted Jan 25, 2023 08:05 PM

    you are right

    lElOUCHE_79_0-1674677066132.png

     

     



  • 16.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 12:03 PM

    Hi Luc

    I corrected it and it's working fine now

     

    Import-Csv -Delimiter ";" -Path ".\VM_List\VMs.csv" |
    ForEach-Object -Process {
    Get-VM -Name $_.VMName | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Memory:$true -Confirm:$false
    }

     

    lElOUCHE_79_0-1674734577801.png

     



  • 17.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 01:40 PM

     
    I made some change on my script and I got an error message

     

    Script:

    Write-Log -FilePath $LogFile -Message "############# creates a new snapshot of virtual machine #############" -Level Control
    ######################################
    $VMList = Get-Content -Path ".\VM_List\VMs.csv"

        foreach ($VM in $VMList) {
            $Snapshot = Get-VM -Name $_VMName | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Memory:$true -Confirm:$false

            if ($null -eq $Snapshot) {
                <# No Snapshots found, Create one at top level. #>
                Write-Log -FilePath $LogFile -Message "[+] No Snapshots found`n" -Level Info
                New-Snapshot($VM)
                Write-Log -FilePath $LogFile -Message "[+] $VM : Snapshots created succesfully`n" -Level Success
            }
            else {
                <# Snapshots Exists, remove before processing #>
                Write-Log -FilePath $LogFile -Message "[-] Snapshots found'n" -Level Info
                Remove-Snapshot($VM)
                Write-Log -FilePath $LogFile -Message "[-] $VM Snapshot removed successfully'n" -Level Success
                New-Snapshot($VM)
                Write-Log -FilePath $LogFile -Message "[+] $VM Snapshot created successfully'n" -Level Success
            }
     
        }
     
    Error message
     
    lElOUCHE_79_0-1674740347756.png

     

    would you please help me to understand where's my error?



  • 18.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 01:43 PM

    Seems you forgot the dot in $_.VMName



  • 19.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 01:54 PM

    good point

    Unfortunately same error



  • 20.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:01 PM

    Since you seem to be reading with Get-Content now, instead of Import-Csv, there is no property named VMName.
    Is the column header row still in the CSV file?
    In that case you will have to skip that 1st row and then just use $_ instead of $_.VMName on the Name parameter.

    But why do read a CSV file with Get-Content?



  • 21.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:06 PM

    Thanks for the reply

    Is the column header row still in the CSV file?
    yes, the structure is like this

    VMName

    VM1;

    VM2;

    But why do read a CSV file with Get-Content?

    I'm reading from CSV file because I will have to create Snapshots for specific VMs



  • 22.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:08 PM

    But normally you read a CSV file with Import-Csv (as I posted in the original snippet), why did you change it to Get-Content?



  • 23.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:11 PM

    ecause I didn't managed to use Import-Csv  in loop



  • 24.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:15 PM

    My snippet is using a loop (Foreach-Object)

    Import-Csv -Delimiter ";" -Path ".\VM_List\VMs.csv" |
        ForEach-Object -Process {
      Get-VM -Name $_.VMName | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Confirm:$false
    }

      



  • 25.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:27 PM

    My bad, I mean this portion of script

        foreach ($VM in $VMList) {
            $Snapshot = Get-VM -Name $_.VMName | New-Snapshot -Name "Snapshot Description" -Description "Created $(Get-Date)" -Memory:$true -Confirm:$false

            if ($null -eq $Snapshot) {
                <# No Snapshots found, Create one at top level. #>
                Write-Log -FilePath $LogFile -Message "[+] No Snapshots found`n" -Level Info
                New-Snapshot($VM)
                Write-Log -FilePath $LogFile -Message "[+] $VM : Snapshots created succesfully`n" -Level Success
            }
            else {
                <# Snapshots Exists, remove before processing #>
                Write-Log -FilePath $LogFile -Message "[-] Snapshots found'n" -Level Info
                Remove-Snapshot($VM)
                Write-Log -FilePath $LogFile -Message "[-] $VM Snapshot removed successfully'n" -Level Success
                New-Snapshot($VM)
                Write-Log -FilePath $LogFile -Message "[+] $VM Snapshot created successfully'n" -Level Success
            }
        }


  • 26.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 02:52 PM

    You can still use that loop I posted.

    Also, when looking for an existing snapshot, just using Get-Date will include the seconds in the name.
    So changes are low that an existing snapshot from that same day will be found.

    As an alternative

    Write-Log -FilePath $LogFile -Message "############# creates a new snapshot of virtual machine #############" -Level Control
    
    Import-Csv -Path ".\VM_List\VMs.csv" -UseCulture | ForEach-Object -Process {
        $snapshot = Get-VM -Name $_.VMName | Get-Snapshot -Name "Created $(Get-Date -Format 'yyyy.MM.dd')" -ErrorAction SilentlyContinue
        if ($snapshot) {
            <# Snapshots Exists, remove before processing #>
            Write-Log -FilePath $LogFile -Message "[-] Snapshots found'n" -Level Info
            Remove-Snapshot($VM)
            Write-Log -FilePath $LogFile -Message "[-] $VM Snapshot removed successfully'n" -Level Success
        }
        New-Snapshot($VM)
        Write-Log -FilePath $LogFile -Message "[+] $VM Snapshot created successfully'n" -Level Success
    }


  • 27.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 05:34 PM

    for sure I'm missing something or doing things in wrong way

     

    lElOUCHE_79_0-1674754458057.png

     



  • 28.  RE: Create Snapshot based on CSV files

    Posted Jan 26, 2023 05:58 PM

    I just copied that from your code.

    What is the meaning of this New-Snapshot($vm) call?
    Is that a function you defined?



  • 29.  RE: Create Snapshot based on CSV files

    Posted Jan 27, 2023 05:14 AM

    New-Snapshot($vm) I'm using this call to create new snapshot by searching the vm from vm list 

     

    I believe I'm doing it incorrectly 



  • 30.  RE: Create Snapshot based on CSV files
    Best Answer

    Posted Jan 27, 2023 07:39 AM

    Yes, I'm afraid so.
    Try something like this

    Write-Log -FilePath $LogFile -Message "############# creates a new snapshot of virtual machine #############" -Level Control
    
    Import-Csv -Path ".\VM_List\VMs.csv" -UseCulture | ForEach-Object -Process {
        $snapshot = Get-VM -Name $_.VMName | Get-Snapshot -Name "Created $(Get-Date -Format 'yyyy.MM.dd')" -ErrorAction SilentlyContinue
        if ($snapshot) {
            <# Snapshots Exists, remove before processing #>
            Write-Log -FilePath $LogFile -Message "[-] Snapshots found'n" -Level Info
            Remove-Snapshot -Snapshot $snapshot -Confirm:$false
            Write-Log -FilePath $LogFile -Message "[-] $VM Snapshot removed successfully'n" -Level Success
        }
        New-Snapshot -VM $_.VMName -Name "Created $(Get-Date -Format 'yyyy.MM.dd')" -Description "Created $(Get-Date -Format 'yyyy.MM.dd')"
        Write-Log -FilePath $LogFile -Message "[+] $VM Snapshot created successfully'n" -Level Success
    }


  • 31.  RE: Create Snapshot based on CSV files

    Posted Jan 29, 2023 07:43 PM

    Thank you