This commit is contained in:
Zack Meier
2026-04-15 15:45:50 -05:00
commit 1d304511b8
613 changed files with 140998 additions and 0 deletions
@@ -0,0 +1,133 @@
<#
.SYNOPSIS
Creates a vCenter scheduled task that will create a virtual machine snapshot.
.DESCRIPTION
Creates a vCenter scheduled task that will create a virtual machine snapshot.
.NOTES
.LINK
https://northdakota.service-now.com/nav_to.do?uri=kb_knowledge.do?sysparm_query=number=KB0017146
#>
[CmdletBinding()]
param (
[Parameter(
Mandatory = $true,
HelpMessage = "The VMware virtual machine name. This is most commonly the FQDN. You can verify the virtual machine name by logging into vCenter. Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back."
)]
[string[]]
$VMName,
[Parameter(Mandatory = $true,
HelpMessage = "The DateTime you want the snapshot to occur.")]
[datetime]
$DateTime = (Get-Date),
[Parameter(Mandatory = $true,
HelpMessage = "How many hours the snapshot will exist. The snapshot will be automatically deleted after the duration. Maximum value is 72 hours.")]
[ValidateRange(1, 72)]
[int]
$DurationHours = 4,
[Parameter(HelpMessage = "Email address that you want vCenter to notify when the snapshot is taken. Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back.")]
[string[]]
$Email
)
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$StartDateTime = $DateTime
$EndDateTime = $StartDateTime.AddHours($DurationHours)
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
$StartDateTimeSql = $StartDateTime.ToString('yyyy/MM/dd HH:mm:ss')
$EndDateTimeSql = $EndDateTime.ToString('yyyy/MM/dd HH:mm:ss')
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "After Connect vCenter" -Verbose
ForEach ($name in $VMName) {
Write-Verbose -Message ("Add record to SQL") -Verbose
$SqlQuery = "INSERT INTO [$SnapshotTable] (VMName, DateTime, RequestedBy, DurationHours,Status,ExpireDateTime,NotifyEmail,PSUJobIdRequest) Values ('$Name', '$StartDateTimeSql', '$RequestedBy', $DurationHours, 'Requested', '$EndDateTimeSql','$Email','$PSUJobId');SELECT SCOPE_IDENTITY();"
Write-Verbose -Message $SqlQuery -Verbose
$SnapshotId = (Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose).Column1
Write-Verbose -Message ("Snapshot ID is $SnapshotId") -Verbose
Write-Verbose -Message "Get SQL record" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE ID='$SnapshotId'"
Write-Verbose -Message $SqlQuery -Verbose
$SqlRecord = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message $SqlRecord -Verbose
Write-Verbose -Message ("Determine description metadata") -Verbose
$MetadataObj = @{
Id = [int]$SnapshotId;
Taken = $StartDateTime;
Expire = $EndDateTime;
RequestedBy = $RequestedBy;
DurationHours = $DurationHours;
PSUJobIdRequest = $PSUJobId;
}
Write-Verbose -Message ("Create VM Scheduled Task for Snapshot " + $SnapshotId) -Verbose
$NewITDVMwareVMSnapshotTaskParams = @{
VMName = $name;
Name = ("AutoSnap_" + $SnapshotId)
Description = $MetadataObj | ConvertTo-Json
DateTime = $StartDateTime;
}
switch ($PSBoundParameters.Keys) {
Email {
$NewITDVMwareVMSnapshotTaskParams.Email = $Email
}
}
try {
New-ITDVMwareVMSnapshotTaskV3 @NewITDVMwareVMSnapshotTaskParams -Verbose -ErrorAction Stop
Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message ($NewITDVMwareVMSnapshotTaskParams.Name + " has been scheduled.") -Verbose
}
catch {
Write-Verbose -Message "ObjectNotFound Error" -Verbose
switch ($Error[0].Exception.ErrorCategory) {
'ObjectNotFound' {
# update SQL with error
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed, ObjectNotFound.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-VMNotFound' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
'Default' {
# update SQL with error
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-GenericError' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Write-Error -Message $Error[0]
}
}
Disconnect-ITDvCenter
# Write-Verbose -Message ("If scheduled task is created successfully, create SNow CHG for this, using scheduled StartDateTime... work TBD") -Verbose
@@ -0,0 +1,59 @@
## TO-DO: update SQL status to Expired-Alerted when a ticket is created, so duplicate tickets are not generated
[CmdletBinding()]
param (
[string]
$VMName,
[int]
$Id, # ??
[switch]
$WhatIf
)
Write-Verbose -Message "Connect to vCenter and ServiceNow"
New-ITDServiceNowSession -Environment Production -Credential $Secret:SnowVMCred
Connect-ITDvCenter -Credential $Secret:svcitdiaasauto
# find all VMs, with VMName if entered
If ($PSBoundParameters.ContainsKey('VMName')) {
Write-Verbose -Message "VMname parameter found $VMName" -Verbose
$VMs = Get-VM -Name $VMName | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
Else {
Write-Verbose -Message "VMname parameter not found" -Verbose
$VMs = Get-VM | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
# find expired snapshots of the VMs
If ($PSBoundParameters.ContainsKey('Id')) {
Write-Verbose -Message "ID parameter found $Id" -Verbose
$AllSnapshots = $VMs | Get-Snapshot | Where-Object Name -Like "AutoSnap_$Id*"
}
Else {
Write-Verbose -Message "ID parameter not found" -Verbose
$AllSnapshots = $VMs | Get-Snapshot | Where-Object Name -Like "AutoSnap_*"
}
ForEach ($Snapshot in $AllSnapshots) {
$SnapshotObj = $Snapshot.Description | ConvertFrom-Json
If ( $SnapshotObj.Expire -lt (Get-Date).AddHours(-24) ) {
$NewITDServiceNowIncidentParams = @{
CallerUsername = 'svcvmwareadm';
ShortDescription = ("VMware Snapshot #" + $SnapshotObj.Id + " cleanup failure.");
Description = ("VMware Snapshot #" + $SnapshotObj.ID + " cleanup failure. Snapshot expired more than 24 hours ago, but it still exists.");
Impact = 3;
Urgency = 3;
Category = 'Systems Platforms - Systems';
Subcategory = 'VMware';
AssignmentGroup = 'NDIT-Computer Systems Windows';
}
New-ITDServiceNowIncident @NewITDServiceNowIncidentParams
}
}
Disconnect-ITDvCenter
@@ -0,0 +1,133 @@
<#####
.SYNOPSIS
Creates a vCenter scheduled task that will create a virtual machine snapshot.
.DESCRIPTION
Creates a vCenter scheduled task that will create a virtual machine snapshot.
.NOTES
.LINK
https://northdakota.service-now.com/kb_view.do?sysparm_article=KB0017146
#>
[CmdletBinding()]
param (
[Parameter(
Mandatory = $true,
HelpMessage = "The VMware virtual machine name. This is most commonly the FQDN. You can verify the virtual machine name by logging into vCenter. Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back."
)]
[string[]]
$VMName = $null,
[Parameter(Mandatory = $true,
HelpMessage = "The DateTime you want the snapshot to occur.")]
[datetime]
$DateTime = (Get-Date),
[Parameter(Mandatory = $true,
HelpMessage = "How many hours the snapshot will exist. The snapshot will be automatically deleted after the duration. Maximum value is 72 hours.")]
[ValidateRange(1, 72)]
[int]
$DurationHours = 4,
[Parameter(HelpMessage = "Email address that you want vCenter to notify when the snapshot is taken. Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back.")]
[string[]]
$Email = $null
)
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$StartDateTime = $DateTime
$EndDateTime = $StartDateTime.AddHours($DurationHours)
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
$StartDateTimeSql = $StartDateTime.ToString('yyyy/MM/dd HH:mm:ss')
$EndDateTimeSql = $EndDateTime.ToString('yyyy/MM/dd HH:mm:ss')
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "After Connect vCenter" -Verbose
ForEach ($name in $VMName) {
Write-Verbose -Message ("Add record to SQL") -Verbose
$SqlQuery = "INSERT INTO [$SnapshotTable] (VMName, DateTime, RequestedBy, DurationHours,Status,ExpireDateTime,NotifyEmail,PSUJobIdRequest) Values ('$Name', '$StartDateTimeSql', '$RequestedBy', $DurationHours, 'Requested', '$EndDateTimeSql','$Email','$PSUJobId');SELECT SCOPE_IDENTITY();"
Write-Verbose -Message $SqlQuery -Verbose
$SnapshotId = (Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose).Column1
Write-Verbose -Message ("Snapshot ID is $SnapshotId") -Verbose
Write-Verbose -Message "Get SQL record" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE ID='$SnapshotId'"
Write-Verbose -Message $SqlQuery -Verbose
$SqlRecord = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message $SqlRecord -Verbose
Write-Verbose -Message ("Determine description metadata") -Verbose
$MetadataObj = @{
Id = [int]$SnapshotId;
Taken = $StartDateTime;
Expire = $EndDateTime;
RequestedBy = $RequestedBy;
DurationHours = $DurationHours;
PSUJobIdRequest = $PSUJobId;
}
Write-Verbose -Message ("Create VM Scheduled Task for Snapshot " + $SnapshotId) -Verbose
$NewITDVMwareVMSnapshotTaskParams = @{
VMName = $name;
Name = ("AutoSnap_" + $SnapshotId)
Description = $MetadataObj | ConvertTo-Json
DateTime = $StartDateTime;
}
switch ($PSBoundParameters.Keys) {
Email {
$NewITDVMwareVMSnapshotTaskParams.Email = $Email
}
}
try {
New-ITDVMwareVMSnapshotTaskV3 @NewITDVMwareVMSnapshotTaskParams -Verbose -ErrorAction Stop
Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message ($NewITDVMwareVMSnapshotTaskParams.Name + " has been scheduled.") -Verbose
}
catch {
Write-Verbose -Message "ObjectNotFound Error" -Verbose
switch ($Error[0].Exception.ErrorCategory) {
'ObjectNotFound' {
# update SQL with error
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed, ObjectNotFound.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-VMNotFound' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
'Default' {
# update SQL with error
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-GenericError' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Write-Error -Message $Error[0]
}
}
Disconnect-ITDvCenter
# Write-Verbose -Message ("If scheduled task is created successfully, create SNow CHG for this, using scheduled StartDateTime... work TBD") -Verbose
@@ -0,0 +1,99 @@
[CmdletBinding()]
param (
[string]
$VMName,
[int]
$Id,
[switch]
$WhatIf
)
$PSUJobId = $UAJob.Id
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
# find all VMs, with VMName if entered
If ($PSBoundParameters.ContainsKey('VMName')) {
Write-Verbose -Message "VMName parameter found $VMName" -Verbose
$VMs = Get-VM -Name $VMName | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
Else {
$VMs = Get-VM | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
# find expired snapshots of the VMs
If ($PSBoundParameters.ContainsKey('Id')) {
Write-Verbose -Message "ID parameter found $Id" -Verbose
$AllSnapshots = $VMs | Get-Snapshot | Where-Object Name -EQ "AutoSnap_$Id"
}
Else {
$AllSnapshots = $VMs | Get-Snapshot | Where-Object Name -Like "AutoSnap_2*" ##### Remove the '2' after SharePoint snapshots are all deleted
}
ForEach ($Snapshot in $AllSnapshots) {
Write-Verbose -Message ("Start Snapshot " + $Snapshot.Description) -Verbose
$SnapshotObj = $null
$SnapshotObj = $Snapshot.Description | ConvertFrom-Json
If ($null -ne $SnapshotObj -and $SnapshotObj.Expire -lt (Get-Date)) {
# remove snapshot if expired
If ($WhatIf) {
Write-Verbose -Message ("What if: Performing the operation Remove-Snapshot on Snapshot " + $Snapshot.Name) -Verbose
}
Else {
Write-Verbose -Message ("VMName: " + $Snapshot.VM.Name + " / Snapshot ID: " + $SnapshotObj.Id + " -- attempting removal") -Verbose
# update SQL status to "Delete-Attempted"
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Delete-AutoAttempt', PSUJobIdDelete = '$PSUJobId' WHERE ID = " + $Snapshot.Name.split('_')[1])
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
# Remove Snapshot
$Snapshot | Remove-Snapshot -Confirm:$false -Verbose
# confirm snapshot is truly gone, then update sql with results
If (Get-VM -Name $Snapshot.VM.Name | Get-Snapshot -Id $SnapshotObj.Id -ErrorAction SilentlyContinue) {
$RemoveStatus = $false
}
Else {
# snapshot does not exist
$RemoveStatus = $true
}
# update SQL
switch ($RemoveStatus) {
$true {
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-AutoSuccess' WHERE ID = " + $Snapshot.Name.split('_')[1])
}
$false {
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-AutoFailure' WHERE ID = " + $Snapshot.Name.split('_')[1])
}
}
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Else {
# do nothing
Write-Verbose -Message ("VMName: " + $Snapshot.VM.Name + " / Snapshot ID: " + $SnapshotObj.Id + " has not expired.") -Verbose
}
}
Disconnect-ITDvCenter
@@ -0,0 +1,3 @@
## To-do: Remove vCenter scheduled tasks for snapshots that are more than 30 days old.
# still need to do this
@@ -0,0 +1,8 @@
# It all starts with a single line of powershell code. TEST TEST TEST moar TEST
Write-Verbose -Message "Start Test-vCenterConnection.ps1" -Verbose
Write-Host $Secret:svcitdiaasauto.username
Connect-ITDvCenter -Credential $Secret:svcitdiaasauto
Get-Datacenter
Disconnect-ITDvCenter
Write-Verbose -Message "End Test-vCenterConnection.ps1" -Verbose
#
@@ -0,0 +1,203 @@
[CmdletBinding()]
param (
[int]
$Id
)
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
# get list of All vCenter Scheduled Tasks
$si = Get-View ServiceInstance
$scheduledTaskManager = Get-View $Si.Content.ScheduledTaskManager
Write-Verbose -Message ("Gathering all scheduled tasks with AutoSnap in the task name, this will take some time")
$AllScheduledTasks = Get-View -Id $scheduledTaskManager.ScheduledTask | Where-Object { $_.Info.Name -like "AutoSnap*" }
Write-Verbose -Message "Get SQL records with status of Scheduled" -Verbose
# get list of Scheduled from database
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Scheduled'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Scheduled status") -Verbose
Write-Verbose -Message "Start Scheduled > Taken Loops"
ForEach ($SqlRecord in @($SqlRecords) ) {
$Snapshot = $null
Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
$Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
If ($Snapshot) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
Write-Verbose -Message ("Setting SQL status to Taken") -Verbose
# if status has changed from requested to taken, update database status field
$TakenDateTimeSql = ($Snapshot.Description | ConvertFrom-Json).Taken.ToString('yyyy/MM/dd HH:mm:ss')
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Taken', TakenDateTime = '" + $TakenDateTimeSql + "' WHERE ID = " + $Snapshot.Name.split('_')[1])
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Else {
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
If ($SqlRecord.DateTime -lt (Get-Date)) {
Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " not found, and its requested datetime has passed") -Verbose
# Update SQL record to status Failed-ScheduledNotTaken
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-ScheduledNotTaken' WHERE ID = " + $SqlRecord.Id)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose
}
Write-Verbose -Message "End Scheduled > Taken Loops"
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
# get list of taken from database
Write-Verbose -Message "Start Taken > Expire Loops"
Write-Verbose -Message "Get SQL records with status of Taken" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Taken'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
# check status of all Taken SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Taken status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
$Snapshot = $null
Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
$Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
If ($Snapshot) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
# if expired datetime is in the past, set status to expired
If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has expired.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1])
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Else {
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
}
# get list of Expired from SQL database
Write-Verbose -Message "Start Expired > Removed Loops"
Write-Verbose -Message "Get SQL records with status of Expired" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Expired'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
# check status of all Expired SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Expired status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
$Snapshot = $null
Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
$Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
If ($Snapshot) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
# if expired datetime is in the past, set status to expired
If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " is expired. Will be removed at next Removal run") -Verbose
#$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1])
#Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Else {
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
}
# get list of requested from SQL database
Write-Verbose -Message "Start Requested > Scheduled Loops"
Write-Verbose -Message "Get SQL records with status of Requested" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Requested'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
# check status of all Requested SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Requested status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
# does the scheduled tasks exist?
If ($AllScheduledTasks | Where-Object { $_.Info.Name -eq ("AutoSnap_" + $SqlRecord.Id + '_' + $SqlRecord.VMName) }) {
# yes - update SQL status to Scheduled
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " vCenter scheduled task exists.") -Verbose
Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Else {
# no
# has date/time passed? (10 minute buffer)
If ($SqlRecord.DateTime -lt (Get-Date).AddMinutes(-10)) {
# yes - set SQL status to Failed-RequestedNotScheduled
Write-Warning -Message ("AutoSnap_" + $SqlRecord.Id + " was not scheduled before its datetime.")
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-RequestedNotScheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Else {
# no ???
}
Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " scheduled task does not exist.")
}
}
Write-Verbose -Message "End Requested > Scheduled Loops"
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
Disconnect-ITDvCenter