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
}
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
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello
In VMs.csv I have 2 VMs and I got the below error message
Do you have an empty line in the CSV?
What exactly is in the CSV?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
no empty line in the CSV
in the CSV file I have
VM_1;
VM_2;
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
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you it's working fine 🙂
One of the VM is Powerd ON, unfortunately, I got the PowerState for both as PowerdOFF
It's a normal behavior?
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?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Get-VM show it as powerd on
strange
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
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ah ! Ok then I should add -Memory switch, I made some search but not able to find how I can solve this
See Example 2 on that page
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
}
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.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
you are right
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
}
@LucD
I made some change on my script and I got an error message
Script:
would you please help me to understand where's my error?
Seems you forgot the dot in $_.VMName
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
good point 🙂
Unfortunately same error 😞
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?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference