update
This commit is contained in:
+153
@@ -0,0 +1,153 @@
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object]
|
||||
$WebhookData
|
||||
)
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'PJaSEgC5HML5ZuZk6wKfZQrpj2XfuQ5svBxbnq2g9M7cQJtFN3iGU4kD4p') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$VMName = $InputParams.HostName
|
||||
$Id = $InputParams.Id
|
||||
$Duration = $InputParams.Duration
|
||||
|
||||
$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
If (@($VM).count -eq 2) { $VM = Get-VM -Name $VMName -Server ($global:DefaultVIServers | Sort-Object Name | select -first 1).Name }
|
||||
|
||||
switch ($Duration) {
|
||||
{$Duration -ge 1 -and $Duration -le 7}
|
||||
{
|
||||
Write-Verbose "Duration = Snapshot"
|
||||
$VMSnapshots = $VM | Get-Snapshot | where-object Description -like "AutoSnap_$Id*"
|
||||
|
||||
If (@($VMSnapshots).count -eq 1) {
|
||||
Write-Verbose "Exactly one snapshot match found"
|
||||
$Taken = $true
|
||||
$VMSnapshot = $VMSnapshots
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoSnap_$Id*")
|
||||
}
|
||||
else {
|
||||
if (@($VMSnapshots | where-object Description -like "AutoSnap_$Id*").count -gt 1) {
|
||||
Write-Error "More than one snapshot match found, abort"
|
||||
Exit
|
||||
}
|
||||
else { Write-Verbose "Snapshot Id #$Id match not found on $VMName" }
|
||||
}
|
||||
}
|
||||
{$Duration -ge 8}
|
||||
{
|
||||
Write-Verbose "Duration = Clone"
|
||||
$VMClones = Get-VM | Where-Object Name -eq ($VMName + "_AutoClone_" + $Id)
|
||||
|
||||
If (@($VMClones).count -eq 1) {
|
||||
Write-Verbose "Exactly one clone match found"
|
||||
$Taken = $true
|
||||
$VMClone = $VMClones
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoClone_$Id*")
|
||||
}
|
||||
else {
|
||||
if (@($VMClones).count -gt 1) {
|
||||
Write-Error "More than one VM clone match found, abort"
|
||||
Exit
|
||||
}
|
||||
else { Write-Verbose "Clone Id #$Id match not found for $VMName" }
|
||||
}
|
||||
}
|
||||
Default {
|
||||
Write-Error "Duration less than zero."
|
||||
}
|
||||
}
|
||||
|
||||
If ($Taken -eq $true) {
|
||||
write-verbose "Updating SharePoint fields named Status and SnapshotTaken"
|
||||
$UrlContextInfo = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one record, stopping"; break }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Taken';
|
||||
SnapshotTaken = $Task.PrevRunTime;
|
||||
AutoExpire = ($Task.Description -split '[\r\n]+')[1].split('_')[1];
|
||||
AutoDelete = ($Task.Description -split '[\r\n]+')[2].split('_')[1];
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
Disconnect-VIServer * -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
# 2021 https://96bdfe01-af80-4575-8f23-e7057184c8f6.webhook.cus.azure-automation.net/webhooks?token=EHlEzPMvDt02gdqMb9wlkdt1FrbmlZjbfQpFTtoIrBc%3d
|
||||
# content-type application/x-www-form-urlencoded
|
||||
# 2022 https://96bdfe01-af80-4575-8f23-e7057184c8f6.webhook.cus.azure-automation.net/webhooks?token=%2b6PP2%2bd3FDLqb4bgMs%2b4V1%2bDAMw0tPxN%2f4Ee0eWMa5Q%3d
|
||||
#
|
||||
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object] $WebhookData
|
||||
)
|
||||
|
||||
function Get-ITDVMwareSharePointSnapshotRequestList {
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
$InvokeWebRequestParams = @{ }
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
$URL = "https://share.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail&$expand=Author/Id'
|
||||
$InvokeWebRequestParams += @{
|
||||
Uri = $URL
|
||||
Method = "Get"
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
}
|
||||
|
||||
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
}
|
||||
|
||||
end {
|
||||
$List.d.results
|
||||
}
|
||||
}
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'VRLEq2Yi7yzWW8fpKNCPB5gUcnHfr9sdhXC53y7gWf5BDtHAKpueFYU4L3N9ZxCWy63znqPGh3AJ2bn43uP7GjzfLcgqYLQRkirMXTKqtHssnNGBrew3gxXkr3mZA3NV7DszpR3kjiLgi3FpRPgUWus') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
|
||||
$UrlContextInfo = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,NotifyEmail&$expand=Author/Id'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$SPListItem = $ListItems | Where-object Id -eq $InputParams.Id
|
||||
If ($SPListItem.Title -ne $InputParams.HostName) {
|
||||
Write-Error ("Web request JSON does not match SharePoint Record for SPListItem.Hostname " + $SPListItem.HostName + " and InputParams.Hostname " + $InputParams.Hostname)
|
||||
Exit
|
||||
}
|
||||
|
||||
$VMName = $InputParams.HostName
|
||||
$SnapTime = [DateTime]$SPListItem.DateTime
|
||||
|
||||
$NotifyEmail = $SPListItem.Author.Email
|
||||
If ($SPListItem.NotifyEmail) { $NotifyEmail = $NotifyEmail + ',' + $SPListItem.NotifyEmail }
|
||||
|
||||
$tryCount = 0
|
||||
#while ($tryCount -lt 5) {
|
||||
try {
|
||||
$tryCount++
|
||||
|
||||
|
||||
|
||||
$SnapName = "AutoSnap_" + $SPListItem.ID
|
||||
$SnapExpireDateTime = $SnapTime.AddDays($SPListItem.Duration)
|
||||
If ($SnapExpireDateTime.DayOfWeek -eq "Saturday" -or $SnapExpireDateTime.DayOfWeek -eq "Sunday") {
|
||||
$SnapExpireDateTime = $SnapExpireDateTime.AddDays(2)
|
||||
}
|
||||
$SnapDeleteDateTime = $SnapExpireDateTime.AddDays(2)
|
||||
|
||||
$SnapDescription = "AutoSnap_" + $InputParams.ID + "`r" + "AutoExpire_$SnapExpireDateTime" + "`r" + "AutoDelete_$SnapDeleteDateTime"
|
||||
$SnapDescription = "AutoSnap_" + 1080 + "`r" + "AutoExpire_$SnapExpireDateTime" + "`r" + "AutoDelete_$SnapDeleteDateTime"
|
||||
$snapMemory = $false
|
||||
$snapQuiesce = $false
|
||||
|
||||
Write-Warning $VMName
|
||||
Write-Warning $SnapName
|
||||
Write-Warning ("SharePoint: " + $SnapTime)
|
||||
If ($SnapTime -lt (Get-Date)) {
|
||||
$SnapTime = (Get-Date).AddSeconds(30)
|
||||
}
|
||||
Write-Warning ("PowerShell: " + $SnapTime)
|
||||
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
If (@($VM).count -eq 2) { $VM = Get-VM -Name $VMName -Server ($global:DefaultVIServers | Sort-Object Name | Select-Object -First 1).Name }
|
||||
$VIServer = $VM.Uid.split('@')[1].split(':')[0]
|
||||
|
||||
$si = Get-View ServiceInstance -Server $VIServer
|
||||
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager -Server $VIServer
|
||||
|
||||
$spec = New-Object VMware.Vim.ScheduledTaskSpec
|
||||
$spec.Name = $SnapName, $VMname -join '_'
|
||||
$spec.Description = "$SnapDescription"
|
||||
$spec.Enabled = $true
|
||||
$spec.Notification = $NotifyEmail
|
||||
|
||||
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
|
||||
$spec.Scheduler.runat = $SnapTime
|
||||
|
||||
$spec.Action = New-Object VMware.Vim.MethodAction
|
||||
$spec.Action.Name = "CreateSnapshot_Task"
|
||||
|
||||
@($SnapName, $SnapDescription, $SnapMemory, $SnapQuiesce) | ForEach-Object {
|
||||
$arg = New-Object VMware.Vim.MethodActionArgument
|
||||
$arg.Value = $_
|
||||
$spec.Action.Argument += $arg
|
||||
}
|
||||
|
||||
# prep for update SharePoint record status
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one result, stopping"; Exit }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $SharePointCredential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
# Create vCenter scheduled task
|
||||
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
|
||||
Start-Sleep -Seconds 3
|
||||
}<#
|
||||
catch [System.Management.Automation.MethodInvocationException] {
|
||||
If ($tryCount -lt 4) {
|
||||
If ($Error[1].Exception -like "*You have attempted to schedule the scheduler at a time*in the past*") {
|
||||
Write-Warning ((Get-Date))# + ": Attempted schedule in past @ $SnapTime, trying again")
|
||||
}
|
||||
write-warning $trycount
|
||||
}
|
||||
Else {
|
||||
write-error "vCenter Snapshot Scheduled Task Creation failed"
|
||||
write-error $error[1]
|
||||
Send-MailMessage -From "vmware@nd.gov" -To "zmeier@nd.gov" -Subject "VMware-Snapshot Schedule Failed - $SnapName" -Body "$SnapName`n$SnapDescription" -SmtpServer apprelay1.nd.gov
|
||||
$Status = "Errored"
|
||||
exit
|
||||
}
|
||||
}#>
|
||||
catch {
|
||||
write-error "vCenter Snapshot Scheduled Task Creation failed default message"
|
||||
write-error $error[1]
|
||||
Send-MailMessage -From "vmware@nd.gov" -To "zmeier@nd.gov" -Subject "VMware-Snapshot Schedule Failed Default Message - $SnapName" -Body "$SnapName`n$SnapDescription" -SmtpServer apprelay1.nd.gov
|
||||
$Status = "Errored"
|
||||
exit
|
||||
}
|
||||
#}
|
||||
|
||||
# update SharePoint record status
|
||||
If ($Status -ne "Errored") { $Status = "Scheduled" }
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = $Status;
|
||||
}
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
$postParams = [PSCustomObject]@{
|
||||
AutomationName = "Infra-VMware";
|
||||
Action = 'Provisioning';
|
||||
Units = 5;
|
||||
Platform = 'PowerShell-VMware-SnapshotNew';
|
||||
}
|
||||
Invoke-RestMethod -Uri http://itdnettools.nd.gov/services/automation-tracking.py -Method POST -Body ($postParams | ConvertTo-Json)
|
||||
|
||||
Disconnect-VIServer -Server * -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
Else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
|
||||
)
|
||||
$StartTime = Get-Date
|
||||
function Get-ITDVMwareSharePointSnapshotRequestList {
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
$URL = "https://share.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail,AutoExpire,AutoDelete&$expand=Author/Id'
|
||||
$InvokeWebRequestParams += @{
|
||||
Uri = $URL;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
}
|
||||
|
||||
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
}
|
||||
|
||||
end {
|
||||
$List.d.results
|
||||
}
|
||||
}
|
||||
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$SnapshotList = Get-ITDVMwareSharePointSnapshotRequestList -Credential $SharePointCredential
|
||||
$ListToRemove = $SnapshotList | Where-Object { $_.Status -eq "Expired, Delete Approved" } | Sort-Object AutoDelete
|
||||
|
||||
ForEach ($SPRecord in $ListToRemove) {
|
||||
$Id = $null
|
||||
$VMName = $null
|
||||
$SnapName = $null
|
||||
|
||||
$Id = $SPRecord.ID
|
||||
$VMName = $SPRecord.Title
|
||||
$SnapName = "AutoSnap_" + $Id
|
||||
|
||||
$SnapshotToRemove = Get-Snapshot -Name $SnapName -VM $VMName
|
||||
$Datastore = Get-VM $VMName | Get-Datastore
|
||||
$ViServer = $SnapshotToRemove.uid.split('@')[1].split(':')[0]
|
||||
|
||||
Write-Warning ($SnapshotToRemove.Name + " for " + $SnapshotToRemove.VM + " on " + $Datastore + " on " + $ViServer)
|
||||
|
||||
try {
|
||||
$SnapshotTaskCount = @(Get-Task -Server $ViServer | Where-Object { $_.Name -eq "RemoveSnapshot_Task" -and $_.State -eq "Running" }).count
|
||||
Write-Warning $SnapshotTaskCount
|
||||
while ($SnapshotTaskCount -ge 1) {
|
||||
$timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
|
||||
Write-Warning "[$timestamp]:$SnapshotTaskCount RemoveSnapshot_Task already running, pausing 60 seconds."
|
||||
Start-Sleep -Seconds 60
|
||||
|
||||
$timestamp = $null
|
||||
$SnapshotTaskCount = @(Get-Task | Where-Object { $_.Name -eq "RemoveSnapshot_Task" -and $_.State -eq "Running" }).count
|
||||
Write-Warning $SnapshotTaskCount
|
||||
}
|
||||
$timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
|
||||
Write-Warning "[$timestamp]:$SnapshotTaskCount RemoveSnapshot_Task already running, starting removal."
|
||||
$SnapshotToRemove | Remove-Snapshot -Confirm:$false
|
||||
}
|
||||
catch {
|
||||
Write-Error "Snapshot Removal failed";
|
||||
Write-Error $Error[1];
|
||||
exit
|
||||
}
|
||||
|
||||
#update SharePoint field
|
||||
Write-Verbose "Exactly one match found, updating SharePoint fields named Status and SnapshotTaken"
|
||||
$UrlContextInfo = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$UrlItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($Id)"
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Removed';
|
||||
SnapshotRemoved = [datetime](Get-Date);
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
}
|
||||
Disconnect-VIServer -Server * -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
$DiffTime = [math]::round((4+((Get-Date) - $StartTime).Minutes),0)
|
||||
$postParams = [PSCustomObject]@{
|
||||
AutomationName = "Infra-VMware";
|
||||
Action = 'Deprovisioning';
|
||||
Units = $DiffTime;
|
||||
Platform = 'PowerShell-VMware-SnapshotRemove';
|
||||
}
|
||||
Invoke-RestMethod -Uri http://itdnettools.nd.gov/services/automation-tracking.py -Method POST -Body ($postParams | ConvertTo-Json)
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object]
|
||||
$WebhookData
|
||||
)
|
||||
|
||||
function Get-ITDVMwareSharePointSnapshotRequestList {
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
$InvokeWebRequestParams = @{ }
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
$URL = "https://share.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail,AutoExpire,AutoDelete&$expand=Author/Id'
|
||||
$InvokeWebRequestParams += @{
|
||||
Uri = $URL;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
}
|
||||
|
||||
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
}
|
||||
|
||||
end {
|
||||
$List.d.results
|
||||
}
|
||||
}
|
||||
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$SnapshotList = Get-ITDVMwareSharePointSnapshotRequestList -Credential $SharePointCredential
|
||||
$ListToUpdate = $SnapshotList | where-object { $_.Status -eq "Scheduled" } | Sort-Object DateTime
|
||||
|
||||
#$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
#If (@($VM).count -eq 2) { $VM = Get-VM -Name $VMName -Server ($global:DefaultVIServers | Sort-Object Name | select -first 1).Name }
|
||||
|
||||
ForEach($SPRecord in $ListToUpdate)
|
||||
{
|
||||
$VM = $null
|
||||
$Taken = $null
|
||||
$VMName = $null
|
||||
$Duration = $null
|
||||
$Id = $null
|
||||
$VMSnapshot = $null
|
||||
$Task = $null
|
||||
|
||||
If( (($SPRecord.DateTime) -as [datetime]).ToLocalTime() -lt (Get-Date) ) # If datetime has passed
|
||||
{
|
||||
$VMName = $SPRecord.Title
|
||||
$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
$Duration = $SPRecord.Duration
|
||||
$Id = $SPRecord.Id
|
||||
|
||||
switch ($Duration) {
|
||||
{$Duration -ge 1 -and $Duration -le 7}
|
||||
{
|
||||
Write-Verbose "Duration = Snapshot"
|
||||
$VMSnapshots = $VM | Get-Snapshot | where-object Description -like "AutoSnap_$Id*"
|
||||
|
||||
If (@($VMSnapshots).count -eq 1) {
|
||||
Write-Verbose "Exactly one snapshot match found"
|
||||
$Taken = $true
|
||||
$VMSnapshot = $VMSnapshots
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoSnap_$Id*")
|
||||
}
|
||||
else {
|
||||
if (@($VMSnapshots).count -gt 1) {
|
||||
Write-Error "More than one snapshot match found, abort"
|
||||
Exit
|
||||
}
|
||||
else {
|
||||
$Taken = $false
|
||||
Write-Verbose "Snapshot Id #$Id match not found on $VMName"
|
||||
Write-Error "Snapshot $Id for $VMName not found."
|
||||
}
|
||||
}
|
||||
}
|
||||
{$Duration -ge 8}
|
||||
{
|
||||
Write-Verbose "Duration = Clone"
|
||||
$VMClones = Get-VM | Where-Object Name -eq ($VMName + "_AutoClone_" + $Id)
|
||||
|
||||
If (@($VMClones).count -eq 1) {
|
||||
Write-Verbose "Exactly one clone match found"
|
||||
$Taken = $true
|
||||
$VMClone = $VMClones
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoClone_$Id*")
|
||||
}
|
||||
else {
|
||||
if (@($VMClones).count -gt 1) {
|
||||
Write-Error "More than one VM clone match found, abort"
|
||||
Exit
|
||||
}
|
||||
else {
|
||||
$Taken = $false
|
||||
Write-Verbose "Clone Id #$Id match not found for $VMName"
|
||||
Write-Error "Clone $Id for $VMName not found."
|
||||
}
|
||||
}
|
||||
}
|
||||
Default {
|
||||
Write-Error "Duration less than zero."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
write-verbose "Updating SharePoint fields named Status and SnapshotTaken"
|
||||
$UrlContextInfo = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$UrlItem = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($Id)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
#Status = 'Taken';
|
||||
Status = If ($Taken -eq $true) {'Taken'} Else {'Errored'};
|
||||
SnapshotTaken = $Task.PrevRunTime;
|
||||
AutoExpire = ($Task.Description -split '[\r\n]+')[1].split('_')[1];
|
||||
AutoDelete = ($Task.Description -split '[\r\n]+')[2].split('_')[1];
|
||||
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
}
|
||||
}
|
||||
|
||||
$postParams = [PSCustomObject]@{
|
||||
AutomationName = "Infra-VMware";
|
||||
Action = 'Provisioning';
|
||||
Units = 1;
|
||||
Platform = 'PowerShell-VMware-SnapshotUpdateStatus';
|
||||
}
|
||||
Invoke-RestMethod -Uri http://itdnettools.nd.gov/services/automation-tracking.py -Method POST -Body ($postParams | ConvertTo-Json)
|
||||
|
||||
Disconnect-VIServer * -Confirm:$false -ErrorAction SilentlyContinue
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"Id": "575",
|
||||
"Hostname":"itdfmauditp1.nd.gov"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"WebhookName": "rh-VMware-UpdateVMSnapshotStatus-prd",
|
||||
"RequestBody": "[\n {\n \"Id\": \"68\",\n \"HostName\": \"itddeqappt1.nd.gov\",\n \"DateTime\": \"2/5/2020 7:00 PM\",\n \"Duration\": \"8\",\n \"NotifyEmail\": \"\"\n }\n]",
|
||||
"RequestHeader": {
|
||||
"Connection": "Close",
|
||||
"Expect": "100-continue",
|
||||
"Host": "s25events.azure-automation.net",
|
||||
"ITD": "PJaSEgC5HML5ZuZk6wKfZQrpj2XfuQ5svBxbnq2g9M7cQJtFN3iGU4kD4p",
|
||||
"x-ms-request-id": "5ee3253c-5bb4-4aea-a950-6149ddb0436e"
|
||||
}
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object] $WebhookData
|
||||
)
|
||||
|
||||
function Get-ITDVMwareSharePointSnapshotRequestList {
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
$InvokeWebRequestParams = @{ }
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
$URL = "https://testshare.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail&$expand=Author/Id'
|
||||
$InvokeWebRequestParams += @{
|
||||
Uri = $URL;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
}
|
||||
|
||||
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
}
|
||||
|
||||
end {
|
||||
$List.d.results
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'w3gVRLEq2Yi7yzWW8fpKNCPTKqtHssnNGBref5BDtxXkr3mZA3NB5gUcnHfr9sdhXC53y7gWHAKpueFYU4L3NMXV7DszCWy63znqPGh3AJ2bn43uP7GjzfLcgqYLQRkirpR3kjiLgi3FpRPgUWus9Zx') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$Id = $InputParams.Id
|
||||
$VMName = $InputParams.Hostname
|
||||
|
||||
$SnapshotList = Get-ITDVMwareSharePointSnapshotRequestList -Credential $SharePointCredential
|
||||
$Request = $SnapshotList | where-object ID -eq $id
|
||||
$SnapName = "AutoSnap_" + $Id
|
||||
|
||||
$SnapshotToRemove = Get-Snapshot -Name $SnapName -VM $VMName
|
||||
$Datastore = Get-VM $VMName | Get-Datastore
|
||||
$ViServer = $SnapshotToRemove.uid.split('@')[1].split(':')[0]
|
||||
|
||||
write-warning ($SnapshotToRemove.Name + " for " + $SnapshotToRemove.VM + " on " + $Datastore + " on " + $ViServer)
|
||||
|
||||
|
||||
#try {
|
||||
$SnapshotTaskCount = @(Get-Task -Server $ViServer | Where-Object {$_.Name -eq "RemoveSnapshot_Task" -and $_.State -eq "Running"}).count
|
||||
write-warning $SnapshotTaskCount
|
||||
while ($SnapshotTaskCount -ge 1) {
|
||||
$timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
|
||||
Write-Warning "[$timestamp]:$SnapshotTaskCount RemoveSnapshot_Task already running, pausing 60 seconds."
|
||||
Start-Sleep -Seconds 60
|
||||
|
||||
$timestamp = $null
|
||||
$SnapshotTaskCount = @(Get-Task | Where-Object {$_.Name -eq "RemoveSnapshot_Task" -and $_.State -eq "Running"}).count
|
||||
write-warning $SnapshotTaskCount
|
||||
}
|
||||
$timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
|
||||
Write-Warning "[$timestamp]:$SnapshotTaskCount RemoveSnapshot_Task already running, starting removal."
|
||||
$SnapshotToRemove | Remove-Snapshot -Confirm:$false -RunAsync
|
||||
<#}
|
||||
catch {
|
||||
Write-Error "Snapshot Removal failed";
|
||||
Write-Error $Error[1];
|
||||
exit
|
||||
}#>
|
||||
|
||||
#update SharePoint field
|
||||
Write-Verbose "Exactly one match found, updating SharePoint fields named Status and SnapshotTaken"
|
||||
$UrlContextInfo = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one result, stopping"; break }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Removed';
|
||||
SnapshotRemoved = [datetime](Get-Date);
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
Disconnect-VIServer -Server * -Confirm:$false
|
||||
}
|
||||
Else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object]
|
||||
$WebhookData
|
||||
)
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'vBxbnq2g9M7cQJtFN3iGU4kD4pPJaSEgC5HML5ZuZk6wKfZQrpj2XfuQ5s') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$VMName = $InputParams.HostName
|
||||
$Id = $InputParams.Id
|
||||
$Duration = $InputParams.Duration
|
||||
|
||||
#$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
|
||||
Write-Verbose "Duration = Clone"
|
||||
$VMClones = Get-VM | Where-Object Name -eq ($VMName + "_AutoClone_" + $Id)
|
||||
|
||||
If (@($VMClones).count -eq 1) {
|
||||
$Taken = $true
|
||||
$VMClone = $VMClones
|
||||
}
|
||||
else {
|
||||
if (@($VMClones).count -gt 1) {
|
||||
Write-Error "More than one VM clone match found, abort"
|
||||
Exit
|
||||
}
|
||||
else { Write-Verbose "Clone Id #$Id match not found for $VMName" }
|
||||
}
|
||||
|
||||
If (@($VMClones).count -eq 1) {
|
||||
$VMClone = $VMClones
|
||||
Write-Verbose "Exactly one clone match found, updating SharePoint fields named Status and SnapshotTaken"
|
||||
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoClone_$Id*")
|
||||
|
||||
If ($Taken -eq $true) {
|
||||
$UrlContextInfo = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one record, stopping"; break }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Taken';
|
||||
SnapshotTaken = $Task.PrevRunTime;
|
||||
AutoExpire = ($Task.Description -split '[\r\n]+')[1].split('_')[1];
|
||||
AutoDelete = ($Task.Description -split '[\r\n]+')[2].split('_')[1];
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
Disconnect-VIServer * -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object]
|
||||
$WebhookData
|
||||
)
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'vBxbnq2g9M7cQJtFN3iGU4kD4pPJaSEgC5HML5ZuZk6wKfZQrpj2XfuQ5s') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$VMName = $InputParams.HostName
|
||||
$Id = $InputParams.Id
|
||||
$Duration = $InputParams.Duration
|
||||
|
||||
$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
If (@($VM).count -eq 2) { $VM = Get-VM -Name $VMName -Server ($global:DefaultVIServers | sort-object Name | select -first 1).Name }
|
||||
|
||||
|
||||
Write-Verbose "Duration = Snapshot"
|
||||
$VMSnapshots = $VM | Get-Snapshot | where-object Description -like "AutoSnap_$Id*"
|
||||
|
||||
If (@($VMSnapshots).count -eq 1) {
|
||||
$Taken = $true
|
||||
$VMSnapshot = $VMSnapshots
|
||||
}
|
||||
else {
|
||||
if (@($VMSnapshots | where-object Description -like "AutoSnap_$Id*").count -gt 1) {
|
||||
Write-Error "More than one snapshot match found, abort"
|
||||
Exit
|
||||
}
|
||||
else { Write-Verbose "Snapshot Id #$Id match not found on $VMName" }
|
||||
}
|
||||
|
||||
If (@($VMSnapshots).count -eq 1) {
|
||||
Write-Verbose "Exactly one snapshot match found, updating SharePoint fields named Status and SnapshotTaken"
|
||||
|
||||
If ($Taken -eq $true) {
|
||||
$UrlContextInfo = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one record, stopping"; break }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Taken';
|
||||
SnapshotTaken = $VMSnapshot.Created;
|
||||
AutoExpire = ($VMSnapshot.Description -split '[\r\n]+')[1].split('_')[1];
|
||||
AutoDelete = ($VMSnapshot.Description -split '[\r\n]+')[2].split('_')[1];
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
Disconnect-VIServer * -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object] $WebhookData
|
||||
)
|
||||
|
||||
function Get-ITDVMwareSharePointSnapshotRequestList {
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
$InvokeWebRequestParams = @{ }
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
$URL = "https://testshare.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail&$expand=Author/Id'
|
||||
$InvokeWebRequestParams += @{
|
||||
Uri = $URL
|
||||
Method = "Get"
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
}
|
||||
|
||||
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
}
|
||||
|
||||
end {
|
||||
$List.d.results
|
||||
}
|
||||
}
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'HAKpueFYU4L3NMXTKqtHssnNGBrew3gVRLEq2Yi7yzWW8fpKNCPB5gUcnHfr9sdhXC53y7gWf5BDtxXkr3mZA3NV7DszpR3kjiLgi3FpRPgUWus9ZxCWy63znqPGh3AJ2bn43uP7GjzfLcgqYLQRkir') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
|
||||
$UrlContextInfo = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List2 = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,NotifyEmail&$expand=Author/Id'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$SPListItem = $ListItems | Where-object Id -eq $InputParams.Id
|
||||
If ($SPListItem.Title -ne $InputParams.HostName) {
|
||||
Write-Error ("Web request JSON does not match SharePoint Record for SPListItem.Hostname " + $SPListItem.HostName + " and InputParams.Hostname " + $InputParams.Hostname)
|
||||
Exit
|
||||
}
|
||||
|
||||
$VMName = $InputParams.HostName
|
||||
$SnapTime = ([DateTime]$SPListItem.DateTime).AddMinutes($Duration * 3)
|
||||
|
||||
$NotifyEmail = $SPListItem.Author.Email
|
||||
If ($SPListItem.NotifyEmail) { $NotifyEmail = $NotifyEmail + ',' + $SPListItem.NotifyEmail }
|
||||
|
||||
$tryCount = 0
|
||||
# while ($tryCount -lt 5) {
|
||||
try {
|
||||
$tryCount++
|
||||
Write-Warning ("SharePoint: " + $SnapTime)
|
||||
If ($SnapTime -lt (Get-Date)) {
|
||||
$SnapTime = (Get-Date).AddSeconds(30)
|
||||
}
|
||||
Write-Warning ("PowerShell: " + $SnapTime)
|
||||
|
||||
$SnapName = "AutoSnap_" + $SPListItem.ID
|
||||
$SnapExpireDateTime = $SnapTime.AddMinutes($SPListItem.Duration * 3)
|
||||
$SnapDeleteDateTime = $SnapExpireDateTime.AddMinutes(30)
|
||||
|
||||
$SnapDescription = "AutoSnap_" + $InputParams.ID + "`r" + "AutoExpire_$SnapExpireDateTime" + "`r" + "AutoDelete_$SnapDeleteDateTime"
|
||||
$snapMemory = $false
|
||||
$snapQuiesce = $false
|
||||
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
If (@($VM).count -eq 2) { $VM = Get-VM -Name $VMName -Server ($global:DefaultVIServers | Sort-Object Name | Select-Object -First 1).Name }
|
||||
|
||||
$VIServer = $VM.Uid.split('@')[1].split(':')[0]
|
||||
|
||||
$si = Get-View ServiceInstance -Server $VIServer
|
||||
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager -Server $VIServer
|
||||
|
||||
$spec = New-Object VMware.Vim.ScheduledTaskSpec
|
||||
$spec.Name = $SnapName, $VMname -join '_'
|
||||
$spec.Description = "$SnapDescription"
|
||||
$spec.Enabled = $true
|
||||
$spec.Notification = $NotifyEmail
|
||||
|
||||
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
|
||||
$spec.Scheduler.runat = $SnapTime
|
||||
|
||||
$spec.Action = New-Object VMware.Vim.MethodAction
|
||||
$spec.Action.Name = "CreateSnapshot_Task"
|
||||
|
||||
@($SnapName, $SnapDescription, $SnapMemory, $SnapQuiesce) | ForEach-Object {
|
||||
$arg = New-Object VMware.Vim.MethodActionArgument
|
||||
$arg.Value = $_
|
||||
$spec.Action.Argument += $arg
|
||||
}
|
||||
|
||||
# prep for update SharePoint record status
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one result, stopping"; Exit }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $SharePointCredential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
# Create vCenter scheduled task
|
||||
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
|
||||
Start-Sleep -Seconds 3
|
||||
}
|
||||
catch [System.Management.Automation.MethodInvocationException] {
|
||||
If ($tryCount -lt 4) {
|
||||
If ($Error[1].Exception -like "*You have attempted to schedule the scheduler at a time*in the past*") {
|
||||
Write-Warning ((Get-Date))# + ": Attempted schedule in past @ $SnapTime, trying again")
|
||||
}
|
||||
write-warning $trycount
|
||||
}
|
||||
Else {
|
||||
write-error "vCenter Snapshot Scheduled Task Creation failed"
|
||||
write-error $error[1]
|
||||
Send-MailMessage -From "vmware@nd.gov" -To "zmeier@nd.gov" -Subject "VMware-Snapshot Schedule Failed - $SnapName" -Body "$SnapName`n$SnapDescription" -SmtpServer apprelay1.nd.gov
|
||||
$Status = "Errored"
|
||||
exit
|
||||
}
|
||||
}
|
||||
catch {
|
||||
write-error "vCenter Snapshot Scheduled Task Creation failed default message"
|
||||
write-error $error[1]
|
||||
Send-MailMessage -From "vmware@nd.gov" -To "zmeier@nd.gov" -Subject "VMware-Snapshot Schedule Failed Default Message - $SnapName" -Body "$SnapName`n$SnapDescription" -SmtpServer apprelay1.nd.gov
|
||||
$Status = "Errored"
|
||||
exit
|
||||
}
|
||||
#}
|
||||
|
||||
# update SharePoint record status
|
||||
If ($Status -ne "Errored") { $Status = "Scheduled" }
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = $Status;
|
||||
}
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
Disconnect-VIServer -Server * -Confirm:$false
|
||||
}
|
||||
Else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
|
||||
)
|
||||
|
||||
function Get-ITDVMwareSharePointSnapshotRequestList {
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
$InvokeWebRequestParams = @{ }
|
||||
If ($Credential) { $InvokeWebRequestParams += @{Credential = $Credential } }
|
||||
Else { $InvokeWebRequestParams += @{UseDefaultCredentials = $true } }
|
||||
|
||||
$URL = "https://testshare.nd.gov/itd/Computer-Systems/Distributed-Systems/VMWare/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000' + '&$select=ID,Title,DateTime,Duration,Author/Name,Author/Title,Author/EMail,Status,NotifyEmail,AutoExpire,AutoDelete&$expand=Author/Id'
|
||||
$InvokeWebRequestParams += @{
|
||||
Uri = $URL;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
}
|
||||
|
||||
$List = (Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
}
|
||||
|
||||
end {
|
||||
$List.d.results
|
||||
}
|
||||
}
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'w3gVRLEq2Yi7yzWW8fpKNCPTKqtHssnNGBref5BDtxXkr3mZA3NB5gUcnHfr9sdhXC53y7gWHAKpueFYU4L3NMXV7DszCWy63znqPGh3AJ2bn43uP7GjzfLcgqYLQRkirpR3kjiLgi3FpRPgUWus9Zx') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$SnapshotList = Get-ITDVMwareSharePointSnapshotRequestList -Credential $SharePointCredential
|
||||
$ListToRemove = $SnapshotList | where-object { $_.Status -eq "Expired, Delete Approved" } | Sort-Object AutoDelete
|
||||
|
||||
ForEach ($SPRecord in $ListToRemove) {
|
||||
$Id = $null
|
||||
$VMName = $null
|
||||
$SnapName = $null
|
||||
|
||||
$Id = $SPRecord.ID
|
||||
$VMName = $SPRecord.Title
|
||||
$SnapName = "AutoSnap_" + $Id
|
||||
|
||||
$SnapshotToRemove = Get-Snapshot -Name $SnapName -VM $VMName
|
||||
$Datastore = Get-VM $VMName | Get-Datastore
|
||||
$ViServer = $SnapshotToRemove.uid.split('@')[1].split(':')[0]
|
||||
|
||||
Write-Warning ($SnapshotToRemove.Name + " for " + $SnapshotToRemove.VM + " on " + $Datastore + " on " + $ViServer)
|
||||
|
||||
try {
|
||||
$SnapshotTaskCount = @(Get-Task -Server $ViServer | Where-Object { $_.Name -eq "RemoveSnapshot_Task" -and $_.State -eq "Running" }).count
|
||||
Write-Warning $SnapshotTaskCount
|
||||
while ($SnapshotTaskCount -ge 1) {
|
||||
$timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
|
||||
Write-Warning "[$timestamp]:$SnapshotTaskCount RemoveSnapshot_Task already running, pausing 60 seconds."
|
||||
Start-Sleep -Seconds 60
|
||||
|
||||
$timestamp = $null
|
||||
$SnapshotTaskCount = @(Get-Task | Where-Object { $_.Name -eq "RemoveSnapshot_Task" -and $_.State -eq "Running" }).count
|
||||
Write-Warning $SnapshotTaskCount
|
||||
}
|
||||
$timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
|
||||
Write-Warning "[$timestamp]:$SnapshotTaskCount RemoveSnapshot_Task already running, starting removal."
|
||||
$SnapshotToRemove | Remove-Snapshot -Confirm:$false
|
||||
}
|
||||
catch {
|
||||
Write-Error "Snapshot Removal failed";
|
||||
Write-Error $Error[1];
|
||||
exit
|
||||
}
|
||||
|
||||
#update SharePoint field
|
||||
Write-Verbose "Exactly one match found, updating SharePoint fields named Status and SnapshotTaken"
|
||||
$UrlContextInfo = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
#$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
#If (@($RecordToModify).count -gt 1) { Write-Error "More than one result, stopping"; break }
|
||||
#$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($Id)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Removed';
|
||||
SnapshotRemoved = [datetime](Get-Date);
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
}
|
||||
Disconnect-VIServer -Server * -Confirm:$false
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $false)]
|
||||
[object]
|
||||
$WebhookData
|
||||
)
|
||||
|
||||
If ($WebhookData) {
|
||||
If ($WebhookData.RequestHeader.ITD -eq 'vBxbnq2g9M7cQJtFN3iGU4kD4pPJaSEgC5HML5ZuZk6wKfZQrpj2XfuQ5s') {
|
||||
Write-Verbose "Header has required data"
|
||||
}
|
||||
Else {
|
||||
Write-Error "Header missing required data"
|
||||
exit;
|
||||
}
|
||||
|
||||
$InputParams = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
|
||||
$vCenterCredential = Get-AutomationPSCredential -Name 'VMware Auto'
|
||||
$SharePointCredential = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
|
||||
|
||||
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -ParticipateInCeip $false -Confirm:$false
|
||||
Connect-VIServer -Server itdvmvc1.nd.gov, itdvmvc2.nd.gov -Credential $vCenterCredential
|
||||
|
||||
$VMName = $InputParams.HostName
|
||||
$Id = $InputParams.Id
|
||||
$Duration = $InputParams.Duration
|
||||
|
||||
$VM = Get-VM -Name $VMName | where-object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
|
||||
If (@($VM).count -eq 2) { $VM = Get-VM -Name $VMName -Server ($global:DefaultVIServers | sort-object Name | select -first 1).Name }
|
||||
|
||||
switch ($Duration) {
|
||||
{$Duration -ge 1 -and $Duration -le 7}
|
||||
{
|
||||
Write-Verbose "Duration = Snapshot"
|
||||
$VMSnapshots = $VM | Get-Snapshot | where-object Description -like "AutoSnap_$Id*"
|
||||
|
||||
If (@($VMSnapshots).count -eq 1) {
|
||||
Write-Verbose "Exactly one snapshot match found"
|
||||
$Taken = $true
|
||||
$VMSnapshot = $VMSnapshots
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoSnap_$Id*")
|
||||
}
|
||||
else {
|
||||
if (@($VMSnapshots | where-object Description -like "AutoSnap_$Id*").count -gt 1) {
|
||||
Write-Error "More than one snapshot match found, abort"
|
||||
Exit
|
||||
}
|
||||
else { Write-Verbose "Snapshot Id #$Id match not found on $VMName" }
|
||||
}
|
||||
}
|
||||
{$Duration -ge 8}
|
||||
{
|
||||
Write-Verbose "Duration = Clone"
|
||||
$VMClones = Get-VM | Where-Object Name -eq ($VMName + "_AutoClone_" + $Id)
|
||||
|
||||
If (@($VMClones).count -eq 1) {
|
||||
Write-Verbose "Exactly one clone match found"
|
||||
$Taken = $true
|
||||
$VMClone = $VMClones
|
||||
$Task = ((Get-View ((Get-View ScheduledTaskManager).ScheduledTask)).info | where-object Description -like "AutoClone_$Id*")
|
||||
}
|
||||
else {
|
||||
if (@($VMClones).count -gt 1) {
|
||||
Write-Error "More than one VM clone match found, abort"
|
||||
Exit
|
||||
}
|
||||
else { Write-Verbose "Clone Id #$Id match not found for $VMName" }
|
||||
}
|
||||
}
|
||||
Default {
|
||||
Write-Error "Duration less than zero."
|
||||
}
|
||||
}
|
||||
|
||||
If ($Taken -eq $true) {
|
||||
write-verbose "Updating SharePoint fields named Status and SnapshotTaken"
|
||||
$UrlContextInfo = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/contextinfo"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlContextInfo;
|
||||
Method = "Post";
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$RequestDigest = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$RequestDigest = $RequestDigest.GetContextWebInformation.FormDigestValue
|
||||
|
||||
$UrlList = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlList;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
$List = Invoke-RestMethod @InvokeWebRequestParams
|
||||
$ListItemEntityTypeFullName = $list.entry.content.properties.ListItemEntityTypeFullName
|
||||
|
||||
$UrlListItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items" + '?$top=10000'
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlListItem;
|
||||
Method = "Get";
|
||||
UseBasicParsing = $true;
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" };
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
$ListItems = ((Invoke-WebRequest @InvokeWebRequestParams) -creplace '"Id":', '"Idx":' | ConvertFrom-Json).d.results
|
||||
|
||||
$header = @{
|
||||
"accept" = "application/json;odata=verbose"
|
||||
"X-RequestDigest" = $RequestDigest
|
||||
"IF-MATCH" = '*'
|
||||
"X-HTTP-Method" = "MERGE"
|
||||
}
|
||||
|
||||
$RecordToModify = $ListItems | Where-Object Id -eq $InputParams.Id
|
||||
If (@($RecordToModify).count -gt 1) { Write-Error "More than one record, stopping"; break }
|
||||
$IDtoModify = $RecordToModify.ID
|
||||
|
||||
$UrlItem = "https://testshare.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VMware-Snapshots')/items($IDtoModify)"
|
||||
$InvokeWebRequestParams = @{
|
||||
Uri = $UrlItem;
|
||||
Method = "Get";
|
||||
Headers = @{ "Accept" = "application/json;odata=verbose" }
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential
|
||||
}
|
||||
|
||||
[PSCustomObject]$SetRecord = @{
|
||||
"__metadata" = @{type = $ListItemEntityTypeFullName };
|
||||
Status = 'Taken';
|
||||
SnapshotTaken = $Task.PrevRunTime;
|
||||
AutoExpire = ($Task.Description -split '[\r\n]+')[1].split('_')[1];
|
||||
AutoDelete = ($Task.Description -split '[\r\n]+')[2].split('_')[1];
|
||||
}
|
||||
|
||||
$body = $SetRecord | ConvertTo-Json
|
||||
$InvokeWebRequestParams = @{
|
||||
|
||||
Uri = $UrlItem;
|
||||
Method = "Post";
|
||||
Body = $body;
|
||||
ContentType = "application/json;odata=verbose";
|
||||
Headers = $header;
|
||||
UseBasicParsing = $true;
|
||||
Credential = $SharePointCredential;
|
||||
}
|
||||
Invoke-RestMethod @InvokeWebRequestParams
|
||||
|
||||
Disconnect-VIServer * -Confirm:$false
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
Write-Error "Runbook must be started from webhook"
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"Id": "{ItemProperty:ID}",
|
||||
"HostName": "{ItemProperty:HostName}",
|
||||
"DateTime": "{ItemProperty:DateTime}",
|
||||
"Duration": "{ItemProperty:Duration}"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"Id": "566",
|
||||
"HostName": "itdscmt1.nd.gov"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user