Skip to content

Commit

Permalink
Merge pull request #1880 from microsoft/bilong-vsstesterrefactor
Browse files Browse the repository at this point in the history
Refactor VSSTester
  • Loading branch information
bill-long authored Nov 17, 2023
2 parents f9d9d57 + 446ef03 commit 6e586af
Show file tree
Hide file tree
Showing 23 changed files with 621 additions and 654 deletions.
1 change: 1 addition & 0 deletions .build/cspell-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,5 @@ vuln
wbxml
Webex
Weve
wevtutil
windir
11 changes: 0 additions & 11 deletions Databases/README.md

This file was deleted.

267 changes: 94 additions & 173 deletions Databases/VSSTester/DiskShadow/Invoke-CreateDiskShadowFile.ps1

Large diffs are not rendered by default.

28 changes: 18 additions & 10 deletions Databases/VSSTester/DiskShadow/Invoke-DiskShadow.ps1
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\Logging\Get-VSSWriter.ps1

function Invoke-DiskShadow {
Write-Host " " $nl
Get-Date
Write-Host "Starting DiskShadow copy of Exchange database: $selDB" -ForegroundColor Green $nl
Write-Host "--------------------------------------------------------------------------------------------------------------"
" "
Write-Host "Running the following command:" $nl
Write-Host "`"C:\Windows\System32\DiskShadow.exe /s $path\DiskShadow.dsh /l $path\DiskShadow.log`"" $nl
Write-Host " "
[OutputType([System.Void])]
param(
[Parameter(Mandatory = $true)]
[string]
$OutputPath,

[Parameter(Mandatory = $true)]
[object]
$DatabaseToBackup
)

Write-Host "$(Get-Date) Starting DiskShadow copy of Exchange database: $Database"
Write-Host " Running the following command:"
Write-Host " `"C:\Windows\System32\DiskShadow.exe /s $OutputPath\DiskShadow.dsh /l $OutputPath\DiskShadow.log`""

#in case the $path and the script location is different we need to change location into the $path directory to get the results to work as expected.
try {
$here = (Get-Location).Path
Set-Location $path
DiskShadow.exe /s $path\DiskShadow.dsh /l $path\DiskShadow.log
Set-Location $OutputPath
DiskShadow.exe /s $OutputPath\DiskShadow.dsh /l $OutputPath\DiskShadow.log
} finally {
Set-Location $here
}
Expand Down
80 changes: 32 additions & 48 deletions Databases/VSSTester/DiskShadow/Invoke-RemoveExposedDrives.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,45 @@
# Licensed under the MIT License.

function Invoke-RemoveExposedDrives {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('CustomRules\AvoidUsingReadHost', '', Justification = 'Do not want to change logic of script as of now')]
param()
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]
param(
[Parameter(Mandatory = $true)]
[string]
$OutputPath,

[Parameter(Mandatory = $true)]
[string[]]
$ExposedDrives
)

function Out-removeDHSFile {
param ([string]$FileLine)
$FileLine | Out-File -FilePath "$path\removeSnapshot.dsh" -Encoding ASCII -Append
$FileLine | Out-File -FilePath "$OutputPath\removeSnapshot.dsh" -Encoding ASCII -Append
}

" "
Get-Date
Write-Host "DiskShadow Snapshots" -ForegroundColor Green $nl
Write-Host "--------------------------------------------------------------------------------------------------------------"
" "
Write-Host " "
if ($null -eq $logSnapVol) {
$exposedDrives = $dbSnapVol
} else {
$exposedDrives = $dbSnapVol.ToString() + " and " + $logSnapVol.ToString()
}
"If the snapshot was successful, the snapshot should be exposed as drive(s) $exposedDrives."
"You should be able to see and navigate the snapshot with File Explorer. How would you like to proceed?"
Write-Host " "
Write-Host "NOTE: It is recommended to wait a few minutes to allow truncation to possibly occur before moving past this point." -ForegroundColor Cyan
Write-Host " This allows time for the logs that are automatically collected to include the window for the truncation to occur." -ForegroundColor Cyan
Write-Host "$(Get-Date) DiskShadow Snapshots"
Write-Host
Write-Host "If the snapshot was successful, the snapshot should be exposed as drive(s) $ExposedDrives."
Write-Host "You should be able to see and navigate the snapshot with File Explorer."
Write-Host
Write-Host "NOTE: It is recommended to wait a few minutes to allow truncation to possibly occur before moving past this point."
Write-Host " This allows time for the logs that are automatically collected to include the window for the truncation to occur."
Write-Host
Write-Host "When ready, choose from the options below:" -ForegroundColor Yellow
" "
Write-Host " 1. Remove exposed snapshot now"
Write-Host " 2. Keep snapshot exposed"
Write-Host " "
Write-Warning "Selecting option 1 will permanently delete the snapshot created, i.e. your backup will be deleted."
" "
$matchCondition = "^[1-2]$"
Write-Debug "matchCondition: $matchCondition"
do {
Write-Host "Selection" -ForegroundColor Yellow -NoNewline
$removeExpose = Read-Host " "
if ($removeExpose -notmatch $matchCondition) {
Write-Host "Error! Please choose a valid option." -ForegroundColor red
}
} while ($removeExpose -notmatch $matchCondition)

$unexposedCommand = "delete shadows exposed $dbSnapVol"
if ($null -ne $logSnapVol) {
$unexposedCommand += $nl + "delete shadows exposed $logSnapVol"

New-Item -Path $OutputPath\removeSnapshot.dsh -type file -Force | Out-Null

$ExposedDrives | ForEach-Object {
Out-removeDHSFile "delete shadows exposed $($_):"
}

if ($removeExpose -eq "1") {
New-Item -Path $path\removeSnapshot.dsh -type file -Force
Out-removeDHSFile $unexposedCommand
Out-removeDHSFile "exit"
& 'C:\Windows\System32\DiskShadow.exe' /s $path\removeSnapshot.dsh
} elseif ($removeExpose -eq "2") {
Write-Host "You can remove the snapshots at a later time using the DiskShadow tool from a command prompt."
Write-Host "Run DiskShadow followed by these commands:"
Write-Host $unexposedCommand
Out-removeDHSFile "exit"

if ($PSCmdlet.ShouldProcess("$ExposedDrives", "Remove exposed drives now?")) {
DiskShadow.exe /s "$OutputPath\removeSnapshot.dsh"
} else {
Write-Host "When you are ready to remove the snapshots, run the following command:"
Write-Host
Write-Host "DiskShadow.exe /s $OutputPath\removeSnapshot.dsh"
Write-Host
}
}
42 changes: 23 additions & 19 deletions Databases/VSSTester/ExchangeInformation/Get-CopyStatus.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@
# Licensed under the MIT License.

function Get-CopyStatus {
if ((($databases[$dbToBackup]).IsMailboxDatabase) -eq "True") {
Get-Date
Write-Host "Status of '$selDB' and its replicas (if any)" -ForegroundColor Green $nl
Write-Host "--------------------------------------------------------------------------------------------------------------"
" "
[array]$copyStatus = (Get-MailboxDatabaseCopyStatus -identity ($databases[$dbToBackup]).name)
($copyStatus | Format-List) | Out-File -FilePath "$path\copyStatus.txt"
for ($i = 0; $i -lt ($copyStatus).length; $i++ ) {
if (($copyStatus[$i].status -eq "Healthy") -or ($copyStatus[$i].status -eq "Mounted")) {
Write-Host "$($copyStatus[$i].name) is $($copyStatus[$i].status)"
} else {
Write-Host "$($copyStatus[$i].name) is $($copyStatus[$i].status)"
Write-Host "One of the copies of the selected database is not healthy. Please run backup after ensuring that the database copy is healthy" -ForegroundColor Yellow
exit
}
}
} else {
Write-Host "Not checking database copy status since the selected database is a Public Folder Database..."
[OutputType([System.Void])]
param(
[Parameter(Mandatory = $true)]
[string]
$ServerName,

[Parameter(Mandatory = $true)]
[object]
$Database,

[Parameter(Mandatory = $true)]
[string]
$OutputPath
)

Write-Host "$(Get-Date) Status of '$Database' and its replicas (if any)"
[array]$copyStatus = (Get-MailboxDatabaseCopyStatus -identity ($Database).name)
($copyStatus | Format-List) | Out-File -FilePath "$OutputPath\copyStatus.txt"
$copyStatus | Format-Table Name, Status | Out-Host
$unhealthyCopies = $copyStatus | Where-Object { $_.Status -ne "Healthy" -and $_.Status -ne "Mounted" }
if ($null -ne $unhealthyCopies) {
Write-Warning "One of the copies of the selected database is not healthy. Please run backup after ensuring that the database copy is healthy"
exit
}
" "
}
30 changes: 10 additions & 20 deletions Databases/VSSTester/ExchangeInformation/Get-Databases.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,15 @@
# Licensed under the MIT License.

function Get-Databases {
Get-Date
Write-Host "Getting databases on server: $serverName" -ForegroundColor Green $nl
Write-Host "--------------------------------------------------------------------------------------------------------------"
" "
[OutputType([System.Array])]
param(
[Parameter(Mandatory = $true)]
[string]
$ServerName
)

[array]$script:databases = Get-MailboxDatabase -server $serverName -status
if ($null -ne (Get-PublicFolderDatabase -Server $serverName)) {
$script:databases += Get-PublicFolderDatabase -server $serverName -status
}

#write-host "Database Name:`t`t Mounted: `t`t Mounted On Server:" -ForegroundColor Yellow $nl
$script:dbID = 0

foreach ($script:db in $databases) {
$script:db | Add-Member NoteProperty Number $dbID
$dbID++
}

$script:databases | Format-Table Number, Name, Mounted, Server -AutoSize | Out-String

Write-Host " " $nl
Write-Host "$(Get-Date) Getting databases on server: $ServerName"
[array]$databases = Get-MailboxDatabase -server $ServerName -status
$databases | Format-Table Name, Mounted, Server -AutoSize | Out-Host
return $databases
}
41 changes: 0 additions & 41 deletions Databases/VSSTester/ExchangeInformation/Get-DbToBackup.ps1

This file was deleted.

28 changes: 16 additions & 12 deletions Databases/VSSTester/ExchangeInformation/Get-ExchangeVersion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,46 @@
# Licensed under the MIT License.

function Get-ExchangeVersion {
Get-Date
Write-Host "Verifying Exchange version..." -ForegroundColor Green $nl
Write-Host "--------------------------------------------------------------------------------------------------------------"
" "
$script:exchVer = (Get-ExchangeServer $serverName).AdminDisplayVersion
[OutputType([System.Void])]
param(
[Parameter(Mandatory = $true)]
[string]
$ServerName
)

Write-Host "$(Get-Date) Verifying Exchange version..."
$exchVer = (Get-ExchangeServer $ServerName).AdminDisplayVersion
$exchVerMajor = $exchVer.major
$exchVerMinor = $exchVer.minor

switch ($exchVerMajor) {
"14" {
$script:exchVer = "2010"
$exchVer = "2010"
}
"15" {
switch ($exchVerMinor) {
"0" {
$script:exchVer = "2013"
$exchVer = "2013"
}
"1" {
$script:exchVer = "2016"
$exchVer = "2016"
}
"2" {
$script:exchVer = "2019"
$exchVer = "2019"
}
}
}

default {
Write-Host "This script is only for Exchange 2013, 2016, and 2019 servers." -ForegroundColor red $nl
Write-Host " This script is only for Exchange 2013, 2016, and 2019 servers."
exit
}
}

Write-Host "$serverName is an Exchange $exchVer server. $nl"
Write-Host " $ServerName is an Exchange $exchVer server."

if ($exchVer -eq "2010") {
Write-Host "This script no longer supports Exchange 2010."
Write-Host " This script no longer supports Exchange 2010."
exit
}
}
23 changes: 23 additions & 0 deletions Databases/VSSTester/Logging/Get-VSSWriter.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

function Get-VSSWriter {
[CmdletBinding()]
param ()

$writersText = vssadmin list writers
if ($LASTEXITCODE) {
Write-Warning $writersText
throw "Unable to list vss writers"
}

for ($lineNumber = 3; $lineNumber -lt $writersText.Count; $lineNumber += 6) {
[PSCustomObject]@{
Name = $writersText[$lineNumber].Substring($writersText[$lineNumber].IndexOf("'") + 1).TrimEnd("'")
Id = $writersText[$lineNumber + 1].Substring($writersText[$lineNumber + 1].IndexOf("{") + 1).TrimEnd("}")
InstanceId = $writersText[$lineNumber + 2].Substring($writersText[$lineNumber + 2].IndexOf("{") + 1).TrimEnd("}")
State = $writersText[$lineNumber + 3].Substring($writersText[$lineNumber + 3].IndexOf(":") + 1).Trim()
LastError = $writersText[$lineNumber + 4].Substring($writersText[$lineNumber + 4].IndexOf(":") + 1).Trim()
}
}
}
27 changes: 12 additions & 15 deletions Databases/VSSTester/Logging/Get-VSSWritersAfter.ps1
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\Get-VSSWriter.ps1

function Get-VSSWritersAfter {
" "
Get-Date
Write-Host "Checking VSS Writer Status: (after backup)" -ForegroundColor Green $nl
Write-Host "--------------------------------------------------------------------------------------------------------------"
" "
" "
$writers = (vssadmin list writers)
$writers > $path\vssWritersAfter.txt
[OutputType([System.Void])]
param(
[Parameter(Mandatory = $true)]
[string]
$OutputPath
)

foreach ($line in $writers) {
if ($line -like "Writer name:*") {
"$line"
} elseif ($line -like " State:*") {
"$line" + $nl
}
}
Write-Host "$(Get-Date) Checking VSS Writer Status: (after backup)"
$writers = Get-VSSWriter
$writers | Export-Csv $OutputPath\vssWritersAfter.csv -NoTypeInformation
$writers | Sort-Object Name | Format-Table | Out-Host
}
Loading

0 comments on commit 6e586af

Please sign in to comment.