UPDManagement.psm1

Function Optimize-UPDSize
{
<#
    .SYNOPSIS
        This function shrinks a UPD VHDX file.
 
    .DESCRIPTION
        This function requires the domain, user name, and the folder path as parameters to function. The function takes the user name and looks up the SID to be used in the file name to find the VHDX file of the UPD.
        Then it will execute an Optimize-VHD command on the VHDX file to compact it.
        You can run this against a single user UPD or against an entire directory/drive of UPDs.
         
        Note: the user CANNOT be logged. If they are the commands will fail. This is because the VHDX file needs to be dismounted or in read-only mode for the commands to work.
 
    .PARAMETER Domain
        This optional parameter sets the domain name to be used in the function.
        Can by NETBIOS or FQDN of the domain.
        Requires UserName and Path parameters.
          
    .PARAMETER UserName
        This optional parameter sets the user name to be used to look up the SID.
        Rquires Domain and Path parameters.
 
    .PARAMETER Path
        This optional parameter sets the folder path to be used to find the VHDX file.
        Must enclose in double quotes if path has a space.
        Must include the trailing \ to denote folder.
        Requires Domain and UserName parameters.
         
    .PARAMETER All
        This is a switch to optimize all VHDXs in a given folder and it's sub folders.
         
    .PARAMETER Log
        This parameter defines the log output location for failed VHDXs.
        You must specify the full path and file name.
        i.e. c:\Temp\log.csv
 
    .INPUTS
        None
 
    .OUTPUTS
        Display results on command line
 
    .EXAMPLE
        Optimize-UPDSize -Domain test.local -UserName jdoe -Path "E:\UPDs\"
         
        This is how to shrink a single user's UPD.
         
    .EXAMPLE
        Optimize-UPDSize -Path "E:\UPDs\" -All -Log "C:\temp\log.csv"
         
        This is how you could recursively shrink all UPDs and log all UPDs that failed to shrink to a csv.
        The CSV can be used as input for the -UserName parameter to rerun the cmdlet for fails.
 
    .LINK
        Optimize-VHD
 
    .NOTES
        Author: Joe Fabrie
                BCT Consulting
                Phone: 559-579-1400
                Email: jfabrie@bctconsulting.com
        Last Edit: 2020-07-20
        Version 1.0 - Initial version
          
#>


    [CmdletBinding()]
    param (

    [Parameter(Mandatory=$false,
        HelpMessage="Put in the NETBIOS or FQDN domain name.")] 
        [string]$Domain,

    [Parameter(Mandatory=$false,
        HelpMessage="Put the user login name")] 
        [string]$UserName,
    
    [Parameter(Mandatory=$true,
        HelpMessage="Put the folder path in to where the UPDs are")]
        [string]$Path,
        
    [Parameter(Mandatory=$false,
        HelpMessage="Put the full file path and file name to stor the log file")]
        [string]$Log,
    
    [Parameter(Mandatory=$false)]
        [switch]$All

    )
    
    Begin {
        $UPDs = Get-ChildItem -Path $Path
    }
   
    Process {
        if ($All -eq $false) {
            $objUser = New-Object System.Security.Principal.NTAccount("$Domain", "$UserName")
            $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
            $PathFE = $Path + "UVHD-" + $strSID.Value + ".vhdx"
            Write-host ("Optimizing " + $ObjUser.Value)
            Optimize-VHD -Path $PathFE -Mode Full
            
        }
        
        else {
            Foreach ($VHDX in $UPDs) {
                $error.clear()
                try {
                    $PathFE = $Path + $VHDX.Name
                    write-host ("Optimizing " + $VHDX.Name)
                    Optimize-VHD -Path $PathFE -Mode Full
                }
                catch {
                    $SIDtoUser = $VHDX.name -replace ".{5}$"
                    $objSID = New-Object System.Security.Principal.SecurityIdentifier ($SIDtoUser)
                    $objUser = $objSID.Translate([System.Security.Principal.NTAccount])
                    $objUser
                    $objUser | Export-CSV -append -Path $Log
                    Write-Host ("Could not optimize " + $objUser)
                }

            }
        }
    }
}