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
}
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
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?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
ecause I didn't managed to use Import-Csv in loop 😞
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
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
My bad, I mean this portion of script
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
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
for sure I'm missing something or doing things in wrong way
I just copied that from your code.
What is the meaning of this New-Snapshot($vm) call?
Is that a function you defined?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
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
Thank you @LucD