Public/Remove-FslOrphanedDisk.ps1

function Remove-FslOrphanedDisk {
    <#
    .SYNOPSIS
        Deletes (or archives) container disks whose owner no longer exists - the
        explicit, WhatIf-first cleanup companion to Get-FslOrphanedDisk.
    .DESCRIPTION
        Takes Get-FslOrphanedDisk output from the pipeline and acts ONLY on
        disks classified as 'Orphaned' (the account no longer exists). Disks in
        any other state - OK, Disabled, Unknown - are skipped: a disabled account
        may come back, and Unknown is by definition not a safe delete.

        With -ArchivePath the disk is moved instead of deleted, preserving the
        container folder name - the cautious first step before reclaiming the
        space for good. Empty container folders are removed after the disk is
        gone. Honors -WhatIf/-Confirm (ConfirmImpact High) and reports one
        result object per disk.
    .PARAMETER InputObject
        Objects from Get-FslOrphanedDisk (need State, Disk, UserName, SizeGB).
    .PARAMETER ArchivePath
        Move the disks here (into a subfolder named after the container folder)
        instead of deleting them.
    .EXAMPLE
        Get-FslOrphanedDisk -Path \\fs01\fslogix$ | Where-Object State -eq 'Orphaned' |
            Remove-FslOrphanedDisk -WhatIf

        Shows exactly which disks would be removed, touches nothing.
    .EXAMPLE
        Get-FslOrphanedDisk -Path \\fs01\fslogix$ | Remove-FslOrphanedDisk -ArchivePath \\fs01\archive$ -Confirm:$false

        Archives every confirmed-orphaned disk; everything else is skipped.
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    [OutputType([pscustomobject])]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [pscustomobject]$InputObject,

        [string]$ArchivePath
    )

    process {
        $state = [string]$InputObject.State
        $diskPath = [string]$InputObject.Disk
        if ($state -ne 'Orphaned') {
            Write-Verbose ("Skipping '{0}': State is '{1}' - only Orphaned disks are removed." -f $diskPath, $state)
            return
        }
        if (-not $diskPath -or -not (Test-Path -LiteralPath $diskPath)) {
            Write-Warning ("Disk '{0}' not found - skipped." -f $diskPath)
            return
        }

        $action = 'Delete orphaned container disk'
        if ($ArchivePath) { $action = ("Archive orphaned container disk to '{0}'" -f $ArchivePath) }

        $performed = 'Skipped'
        $destination = ''
        if ($PSCmdlet.ShouldProcess($diskPath, $action)) {
            try {
                if ($ArchivePath) {
                    $folderName = Split-Path (Split-Path $diskPath -Parent) -Leaf
                    $targetDir = Join-Path $ArchivePath $folderName
                    if (-not (Test-Path -LiteralPath $targetDir)) {
                        New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
                    }
                    $destination = Join-Path $targetDir (Split-Path $diskPath -Leaf)
                    Move-Item -LiteralPath $diskPath -Destination $destination -Force -ErrorAction Stop
                    $performed = 'Archived'
                }
                else {
                    Remove-Item -LiteralPath $diskPath -Force -ErrorAction Stop
                    $performed = 'Deleted'
                }

                # Remove the container folder once it holds nothing else.
                $parent = Split-Path $diskPath -Parent
                if ((Test-Path -LiteralPath $parent) -and @(Get-ChildItem -LiteralPath $parent -Force -ErrorAction SilentlyContinue).Count -eq 0) {
                    Remove-Item -LiteralPath $parent -Force -ErrorAction SilentlyContinue
                }
            }
            catch {
                Write-Warning ("Could not remove '{0}': {1}" -f $diskPath, $_.Exception.Message)
                $performed = 'Failed'
            }
        }

        [pscustomobject]@{
            PSTypeName  = 'FSLogixDoctor.DiskCleanup'
            Disk        = $diskPath
            UserName    = [string]$InputObject.UserName
            SizeGB      = $InputObject.SizeGB
            Action      = $performed
            Destination = $destination
        }
    }
}