david62277

FSLogix Profile Compacting Script

Aug 25th, 2017
4,982
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #Requires -Version 5
  2. #Requires -RunAsAdministrator
  3. #Requires -Module Hyper-V
  4. <#
  5. Written by David Ott
  6. I stole some code from www.thesurlyadmin.com (set-alternatingrows function)
  7. This script will compact FSLogix VHD/VHDX profiles in the profile share.  It would also work for
  8. any directory containing VHD/VHDX files.
  9. Test before using!!
  10. Search for "#####" to find the sections you need to edit for your environment
  11. #>
  12. Function Set-AlternatingRows {
  13.     [CmdletBinding()]
  14.     Param(
  15.         [Parameter(Mandatory,ValueFromPipeline)]
  16.         [string]$Line,
  17.        
  18.         [Parameter(Mandatory)]
  19.         [string]$CSSEvenClass,
  20.        
  21.         [Parameter(Mandatory)]
  22.         [string]$CSSOddClass
  23.     )
  24.     Begin {
  25.         $ClassName = $CSSEvenClass
  26.     }
  27.     Process {
  28.         If ($Line.Contains("<tr><td>"))
  29.         {   $Line = $Line.Replace("<tr>","<tr class=""$ClassName"">")
  30.             If ($ClassName -eq $CSSEvenClass)
  31.             {   $ClassName = $CSSOddClass
  32.             }
  33.             Else
  34.             {   $ClassName = $CSSEvenClass
  35.             }
  36.         }
  37.         Return $Line
  38.     }
  39. }
  40. function checkFileStatus($filePath)
  41.     {
  42.             $fileInfo = New-Object System.IO.FileInfo $filePath
  43.  
  44.         try
  45.         {
  46.             $fileStream = $fileInfo.Open( [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read )
  47.             $filestream.Close()
  48.             return $false
  49.         }
  50.         catch
  51.         {
  52.            
  53.             return $true
  54.         }
  55.     }
  56. function vhdmount($v) {
  57. try {
  58. Mount-VHD -Path $v -ReadOnly -ErrorAction Stop
  59. return "0"
  60. } catch {
  61. return "1"
  62. }
  63. }
  64. function vhdoptimize($v) {
  65. $i = "0"
  66. $o = [math]::Round((gi $v | select -expand length)/1mb,2)
  67. try {
  68. Optimize-VHD $v -Mode Full -ErrorAction stop
  69. $r = 0
  70. } catch {
  71. $r = 1
  72. }
  73. $n = [math]::Round((gi $v | select -expand length)/1mb,2)
  74. $dif = [math]::Round(($o-$n),2)
  75. $i | select @{n='VHD';e={Split-Path $v -Leaf}},@{n='Before_MB';e={$o}},@{n='After_MB';e={$n}},@{n='Reduction_MB';e={$dif}},@{n='Success';e={if ($r -eq "0"){$true} else {$false}}},@{n='VHD_Fullname';e={$v}}
  76. }
  77. function vhddismount($v) {
  78. try {
  79. Dismount-VHD $v -ErrorAction stop
  80. return "0"
  81. } catch {
  82. return "1"
  83. }
  84. }
  85. $smtpserver = "smtpserver.fqdn" ##### SMTP Server
  86. $to = "your email address" ##### email report to - "email1","email2" for multiple
  87. $from = "fslogixreport@yourcompany.com" ##### email from
  88. $rootfolder = "\\server\profile_share" ##### root path to vhd(x) files
  89. $vhds = (gci $rootfolder -recurse -Include *.vhd,*.vhdx).fullname
  90. [System.Collections.ArrayList]$info = @()
  91. $t = 0
  92. foreach ($vhd in $vhds) {
  93. $locked = checkFileStatus -filePath $vhd
  94. if ($locked -eq $true) {
  95. "$vhd in use, skipping."
  96. $info.add(($t | select @{n='VHD';e={Split-Path $vhd -Leaf}},@{n='Before_MB';e={0}},@{n='After_MB';e={0}},@{n='Reduction_MB';e={0}},@{n='Success';e={"Locked"}},@{n='VHD_Fullname';e={$vhd}})) | Out-Null
  97. continue
  98. }
  99. $mount = vhdmount -v $vhd
  100. if ($mount -eq "1") {
  101. $e = "Mounting $vhd failed "+(get-date).ToString()
  102. Send-MailMessage -SmtpServer $smtpserver -From $from -To $to -Subject "FSLogix VHD(X) ERROR" -Body "$e" -Priority High -BodyAsHtml
  103. break
  104. }
  105. $info.add((vhdoptimize -v $vhd)) | Out-Null
  106. $dismount = vhddismount -v $vhd
  107. if ($dismount -eq "1") {
  108. $e = "Failed to dismount $vhd "+(get-date).ToString()
  109. Send-MailMessage -SmtpServer $smtpserver -From $from -To $to -Subject "FSLogix VHD(X) ERROR" -Body "$e" -Priority High -BodyAsHtml
  110. break
  111. }
  112. }
  113. $Header = @"
  114. <style>
  115. TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;width: 95%}
  116. TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
  117. TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
  118. .odd { background-color:#ffffff; }
  119. .even { background-color:#dddddd; }
  120. </style>
  121. "@
  122. $date = Get-Date
  123. $timestamp = get-date $date -f MMddyyyyHHmmss
  124. ##### uncomment the next 2 lines if you would like to save a .htm report (also 2 more at the end)
  125. #$out = Join-Path ([environment]::GetFolderPath("mydocuments")) ("FSLogix_Reports\VHD_Reduction_Report_$timestamp.htm")
  126. #if (!(test-path (Split-Path $out -Parent))) {New-Item -Path (Split-Path $out -Parent) -ItemType Directory -Force | Out-Null}
  127. $before = ($info.before_mb | measure -Sum).Sum
  128. $after = ($info.after_mb | measure -Sum).Sum
  129. $reductionmb = ($info.reduction_mb | measure -Sum).sum
  130. $message = $info | sort After_MB -Descending | ConvertTo-Html -Head $header -Title "FSLogix VHD(X) Reduction Report" -PreContent "<center><h2>FSLogix VHD(X) Reduction Report</h2>" -PostContent "</center><br><h3>Pre-optimization Total MB: $before<br>Post-optimization Total MB: $after<br>Total Reduction MB: $reductionmb</h3>"| Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd
  131. ##### comment the next line if you do not wish the report to be emailed
  132. Send-MailMessage -SmtpServer $smtpserver -From $from -To $to -Subject ("FSLogix VHD(X) Reduction Report "+($date).ToString()) -Body "$message" -BodyAsHtml
  133. ##### uncomment the next 2 lines to save the report to your My Documents\FSLogix_Reports directory, and open it in your default browser
  134. #$message | Out-File $out
  135. #Invoke-Item $out
RAW Paste Data