PowerShell Scripting Disclaimer:
This script is provided "as is" for the purpose of illustrating how product tasks may be performed in conjunction with PowerShell. Support shall not be liable for any direct, indirect, incidental, consequential, or other damage alleged in connection with the furnishing or use of this script or of the principles it demonstrates. See PowerShell Scripting Support for more information.
A Powershell script has been prepared to address the issue. Information about how to use the script can be obtained by running
# get-help .\mountcheck.ps1 -full
in an elevated PowerShell 3.0 console.
To summarize, the script must be run on a core server with the core service running. If ran without any parameters, the newest 3 recovery points will be checked with the "Windows","System Volume Information","Program Files (x86)","Program Files" folders and the "*.exe","*.dll" files excluded.
The results are recorded by default in c:\temp\RPs.csv (the temp directory needs to exist).
The log file contains the core name, the server name, the volumes that were checked, the recovery point number and date (please note that the number changes in concordance with the rollups result based on the retention policy), the file sampler that was read and timestamp information.
The commented code is shown below between horizontal lines and attached to the KB.
Please note that the AppAssure Powershell mounting commands are executed before the recovery point is properly mounted so some suplemental checkings had to be performed.
-----------------------------------------------------------------------------
.Synopsis
Checks AppAssure Recovery Points
.Description
Checks AppAssure Recovery Points taking into account the protected server, clusters and replicated servers on the core, the desired number of mount points for the operation, the folders to be excluded (i.e. windows) and the files to be excluded (i.e. *.dll).
.PARAMETER mountpath
the path where the mounting process is executed (default c:\M)
.PARAMETER folderexclusions
(default: "Windows","System Volume Information","Program Files (x86)","Program Files")
.PARAMETER fileexclusions
(default: "*.exe","*.dll")
.PARAMETER lastrp
(the number of recovery points to be considered, beginning with the newest ones, default: 3)
.PARAMETER file
(default: c:\temp\RPS.csv; please note that if the log file is already present an extension which includes the date and time of creation is added to the file name)
.Example
.\MountCheck.ps1 -folderexclusions "*"
.Example
.\Catalog.ps1 -lastrp all
.Example
.\Catalog.ps1 -folderexclusions "Windows","System Volume Information","Program Files (x86)","Program Files" -file c:\temp\log.csv -lastrp 1
#>
#Parameters
param(
$mountpath = "C:\M",
$file = "c:\temp\RPs.csv",
[array]$folderexclusions =("Windows","System Volume Information","Program Files (x86)","Program Files"),
[array]$fileexclusions=("*.exe","*.dll"),
$lastrp=3
)
#prepare log if multiples are present
$suffix=(get-date).tostring("yyyy-MM-dd-hh-mm-ss-tt")
if(!(test-path $file)){$file= $file.replace(".","$($suffix).") }
$startlocation = get-location
cls
Write-Host "Recovery Points Check`r`n---------------------`r`n"
$core=$env:computername
#Attention user about exclusions
Write-host "`r`nExcluded Folders" -f Yellow
$folderexclusions
Write-host "`r`nExcluded Files" -f Yellow
$fileexclusions
#get machines to check
$servers = (get-protectedservers).displayname
$replicatedServers=(get-replicatedservers).displayname
$nodes = (Get-Clusters).displayname
$clusters= ((Get-Clusters).parentclusterdisplayname | group ($_.parentclusterdisplayname)).name
$protectedservers = $servers+ $replicatedservers + $nodes + $clusters | sort-object
#Loop through protected machines
foreach ($protectedserver in $protectedservers){
#local settings to avoid undue errors
$lastcatalog=@()
if(!(test-path $mountpath)){new-item -Path $mountpath -ItemType directory}
set-location $mountpath
#make sure that nothing is already mounted in the folder
Remove-Mount -path $mountpath -ErrorAction SilentlyContinue
#get rps
$allrps = Get-RecoveryPoints -ProtectedServer $protectedserver -Number $lastrp
#get volumes
foreach ($rp in $allrps){
$vols = ((($rp.VolumeImageSummaries).volumename).displayname).replace("\","")
#More messages
write-host "`r`nChecking Server $protectedserver, last $lastrp Recovery Points" -f Yellow
write-host "`r`nFound Volumes $vols" -f Yellow
write-host "`r`nAttempting to dismount previous recovery points" -f Yellow
Remove-Mount -path $mountpath -ErrorAction SilentlyContinue
#Mounting
write-host "`r`nMounting Recovery point number $($rp.number) with the Date-Time Stamp: $(($rp.datetimestamp).ToLocalTime()) EST" -f Yellow
try{
New-Mount -protectedserver $protectedserver -rpn $rp.number -Path $mountpath -ErrorAction Stop
}
catch {Write-host "Cannot mount Recovery Point on $protectedserver RPN: $($rp.number)" -f Red; break}
#check when mount is complete
$command = "cmd.exe /C dir $mountpath"
do {
$checklines = @()
$junctioncheck0 =@(Invoke-Expression -Command:$command)
$junctioncheck = $junctioncheck0[7..($junctioncheck0.count-3)]
foreach ($line in $junctioncheck){
[array]$checkline = $line -split "\s+"
$obj = [pscustomobject]@{Date=($checkline[0]+" "+$checkline[1]+" "+$checkline[2]);Type=$checkline[3];Folder=$checkline[4];ID=$checkline[5]}
$checklines +=$obj
}
$checklines | ft
$totalx = 51*($checklines.count)
$total = 0
foreach ($id in $checklines)
{
$total += ($id.id).length
}
if ($total -lt $totalx){write-host "waiting..." -f yellow}else{write-host "Done!" -f yellow}
start-sleep 5
}while ($total -ne $totalx)
$location = Get-Location
#deal with each drive separately
$folderlist = @()
foreach($v in $checklines){
set-location "$mountpath\$($v.Folder)"
#get folder list on selected drive
try{
$yyy = Get-ChildItem -Exclude $folderexclusions -path "$mountpath\$($v.Folder)" -force -ErrorAction Stop| Where { $_.PSIsContainer } | Select-Object FullName
$folderlist +=$yyy
}catch {Write-host "ERROR: ($mountpath\$($v.Folder)) is not accessible" -f Red; break}
}
#get the list of files
$catalogfiles = @()
foreach ($folder in $folderlist){
$folder
$zzz = Get-ChildItem -Path ($folder.FullName) -Force -Erroraction silentlycontinue -exclude $fileexclusions| Where { $_.Mode[0] -ne "d" } |Select-Object -property FullName,LastWriteTime,CreationTime,LastAccesstime
$catalogfiles += $zzz
}
#get process files
$finalcatalog = @()
foreach ($catalogline in $catalogfiles){
$filepath = (split-path $catalogline.fullname -Parent).replace("$mountpath\","").Replace("__",":")
$filename = split-path $catalogline.fullname -Leaf
$entryline = [pscustomobject]@{Core=$core;Protectedserver=$rp.agenthostname;Volumes=([string]::Join(", ",$vols));RP_Number=$rp.number;RP_Date=$rp.DateTimestamp;Path=$filepath;Filename=$filename;LastWriteTime=$catalogline.LastWriteTime;CreationTime=$catalogline.CreationTime;LastAccesstime=$catalogline.LastAccessTime}
$finalcatalog +=$entryline
}
$lastcatalog +=$finalcatalog
}
set-location $location
#process results (screen and file)
$lastcatalog | ft
$lastcatalog | select-object -property Core,Protectedserver,volumes,RP_Number,RP_Date,Path,Filename,LastWriteTime,CreationTime,LastAccesstime | export-csv -Path $file -Force -NoTypeInformation -Append
}
set-location $startlocation
#process results
#Invoke-Item $file
$postprocess = import-csv -path $file
$postprocess | group-object -property protectedserver,volumes | Out-GridView -PassThru
$postprocess | Out-GridView -PassThru
-----------------------------------------------------------------------------
© ALL RIGHTS RESERVED. Feedback Terms of Use Privacy Cookie Preference Center