Automating Google Cloud Platform Snapshots with PowerShell

As part of a project I am working on, I needed a way to automate disk snapshot creation and retention on Google Cloud Platform.  I found several good examples of how to do this in BASH scripts etc.  However, I was unable to find anything in native PowerShell that I liked.  So, I wrote some scripts and decided to publish them here and on GitHub in the hope of helping someone else.

  • create-snaps.ps1 automates snapshot creation.
  • remove-snaps.ps1 automates snapshot cleanup based on the age of the snapshot.

Obviously, you will need to schedule these to run at some interval.  I’ve used Windows task scheduler for that purpose, and it seems to work great.

Obvious Warning: Please use these scripts at your own risk. I accept no responsibility for your use of them. However, if you run into any issues please let me know so I can work to improve them.

create-snaps.ps1

[code language=”powershell”]
# Set the path and file name for PowerShell transcripts (logs) to be written to.
$LogPath = "c:\logs\powershell\snaps\"
$LogFile = Get-Date -Format FileDateTimeUniversal
$TranscriptFileName = $LogPath + $LogFile +".txt"

# Start the transcript.
Start-Transcript -Path $TranscriptFileName

#Set the GCP project.
$Project = "put-your-gcp-project-here-12345"

#Set the zone(s) where the disks are that you would like to take snapshots of.
$Zones = "us-east1-d", "us-central1-c"

#Record the date that the snapshots started.
$StartTime = Get-Date

#Go snapshot all of the disks in the zones identified above.
foreach ($Zone in $Zones) {
$DisksInZone = Get-GceDisk -Project $Project -zone $Zone | foreach { $_.Name }

foreach ($Disk in $DisksInZone) {
Write-Host "=========================================="
Write-Host "$Zone "-" $Disk"
Write-Host "=========================================="
Add-GceSnapshot -project $Project -zone $Zone $Disk #In the future we could clean this output up a bit.
}
}

#Record the date that the snapshots ended.
$EndTime = Get-Date

#Print out the start and end times.
Write-Host "=========================================="
Write-Host "Started at:" $StartTime
Write-Host "Ended at:" $EndTime
Write-Host "=========================================="

#Stope the transcript.
Stop-Transcript

#Send the PowerShell transcript (log) by email. You can delete this entire section if you don’t want log copies delivered by email.
#Google Cloud Platform blocks direct outbound mail on port 25. Reference: https://cloud.google.com/compute/docs/tutorials/sending-mail/

#Mail Server Settings
$smtpServer = "mail.yourdomainname.com"
$smtpPort = "2525" #Don’t put 25 here it will not work. See link above.

$att = new-object Net.Mail.Attachment($TranscriptFileName)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer, $smtpPort)

# Set the email from / to / subject / body / etc here:
$msg.From = "gcpsnapshots@yourdomainname.com"
$msg.To.Add("you@yourdomainname.com")
$msg.Subject = "GCP Snapshot Report"
$msg.Body = "Please see the attached PowerShell transcript."

# Attach the log and ship it.
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
[/code]

remove-snaps.ps1

[code language=”powershell”]
# Set the path and file name for PowerShell transcripts (logs) to be written to.
$LogPath = "c:\logs\powershell\snaps\"
$LogFile = Get-Date -Format FileDateTimeUniversal
$TranscriptFileName = $LogPath + $LogFile +".txt"

# Start the transcript.
Start-Transcript -Path $TranscriptFileName

#Set the project.
$Project = "put-your-gcp-project-here-12345"

#Record the date / time that the snapshot cleanup started.
$StartTime = Get-Date

#Choose what snaps to remove. Essentially, the script takes the current date / time subtracts 30 days and sets a variable ($deletable). Is delatable even a word? Anyway… Any snaps older than that variable get removed. Obviously, you could tweak this number of days to fit your needs.
$deleteable = (Get-Date).AddDays(-30)

#Log what date and time we set $deleteable to.
Write-Host "Deleting snapshots older than:" $deleteable

#Delete the actual snaps.
$snapshots = Get-GceSnapshot
foreach ($snapshot in $snapshots) {
$snapshotdate = get-date $snapshot.CreationTimestamp
if ($snapshotdate -lt $deleteable) {
Write-Host Removing snapshot: $snapshot.Name
Remove-GceSnapshot $snapshot.Name
}
}

#Record the date / time that the snapshot cleanup ended.
$EndTime = Get-Date

#Print out the start and end times.
Write-Host "=========================================="
Write-Host "Started at:" $StartTime
Write-Host "Ended at:" $EndTime
Write-Host "=========================================="

#Stope the transcript.
Stop-Transcript

#Send the PowerShell transcript (log) by email. You can delete this entire section if you don’t want log copies delivered by email.
#Google Cloud Platform blocks direct outbound mail on port 25. Reference: https://cloud.google.com/compute/docs/tutorials/sending-mail/

#Mail Server Settings
$smtpServer = "mail.yourdomainname.com"
$smtpPort = "2525" #Don’t put 25 here – it will not work. See link above.

$att = new-object Net.Mail.Attachment($TranscriptFileName)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer, $smtpPort)

# Set the email from / to / subject / body / etc here:
$msg.From = "gcpsnapshots@yourdomainname.com"
$msg.To.Add("you@yourdomainname.com")
$msg.Subject = "GCP Snapshot Cleanup Report"
$msg.Body = "Please see the attached PowerShell transcript."

# Attach the log and ship it.
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
<pre>[/code]