Public/Remove-VMConnectConfig.ps1
#.ExternalHelp VMConnectConfig-help.xml function Remove-VMConnectConfig { [CmdletBinding(ConfirmImpact = 'Medium', DefaultParameterSetName = 'Name', HelpURI='https://thegraffix.github.io/VMConnectConfig/remove-vmconnectconfig.html', SupportsShouldProcess)] [Alias('rvmc')] param ( [Parameter(Mandatory, ParameterSetName = 'All')] [switch]$All, [Parameter(Mandatory, ParameterSetName = 'Deleted')] [switch]$Deleted, [switch]$Force, [Parameter(Mandatory, ParameterSetName = 'Id', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('VMId')] [ValidateNotNullOrEmpty()] [System.Guid[]]$Id, [Parameter(Mandatory, ParameterSetName = 'InputObject', Position = 0, ValueFromPipeline)] [System.Management.Automation.PSTypeName('VMConnectConfig')]$InputObject, [Parameter(Mandatory, ParameterSetName = 'Name', Position = 0, ValueFromPipeline)] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [System.String[]]$Name, [Parameter(Mandatory, ParameterSetName = 'Nuke')] [switch]$Nuke ) begin { # This is a workaround for a bug where advanced functions can output an error if "-ErrorAction/-WarningAction Ignore" are used. if ($ErrorActionPreference -eq 'Ignore') {$ErrorActionPreference = 'Ignore'} if ($WarningPreference -eq 'Ignore') {$WarningPreference = 'Ignore'} $null = Test-VMConfigFolder $fileAttributeNormal = [System.IO.FileAttributes]::Normal [System.String[]]$filesToRemoveList = @() $uiOption = [Microsoft.VisualBasic.FileIO.UIOption]::OnlyErrorDialogs } #begin process { if ($PSCmdlet.ParameterSetName -ne 'Nuke') { $allConfigFiles = Get-AllConfigFiles } switch ($PSCmdlet.ParameterSetName) { 'All' { $filesToRemoveList = $allConfigFiles.FullName break } # -All 'Deleted' { Write-VMVerbose -Function Remove-VMConnectConfig -Category Reading -Message ($MsgTable.GettingConfigFilesForDeletedVirtualMachines -f $VMConfigFolder) $filesToRemoveList = (Get-VMConnectConfig -Deleted -ErrorAction SilentlyContinue -Verbose:$false).Path break } # -Deleted 'Id' { foreach ($vmGuid in $Id) { $files = @() $files = [System.String[]](($allConfigFiles | Where-Object {$_.Name -match "vmconnect\.rdp\.$vmGuid.*\.config"}).FullName) if (($files.Count -eq 0) -or ([System.String]::IsNullOrEmpty($files))) { $errMsg = ($MsgTable.ConfigFileNotFoundIdError -f $VMConfigFolder, $vmGuid) $errParams = @{ Category = $ErrorCatObjectNotFound Exception = New-Object -TypeName 'System.ArgumentException' -ArgumentList $errMsg Message = $errMsg } Write-Error @errParams } #if no .config file(s) found. else { foreach ($file in $files) { $filesToRemoveList += $file } } } #foreach ($vmGuid in $Id) break } # -Id 'InputObject' { foreach ($file in $InputObject.Path) { $filesToRemoveList += $file } break } # -InputObject 'Name' { foreach ($vmName in $Name) { $files = @() try { $files = [System.String[]]((Select-Xml -Path $allConfigFiles.FullName -XPath $VMNameXPath | Where-Object {$_.Node.Value -like $vmName}).Path) } #try catch { # Do nothing. This is to fully suppress terminating errors from the Select-Xml cmdlet when the 1.0 directory exists but is empty. } #catch if (($files.Count -eq 0) -or ([System.String]::IsNullOrEmpty($files))) { $errMsg = ($MsgTable.ConfigFileNotFoundNameError -f $VMConfigFolder, $vmName) $errParams = @{ Category = $ErrorCatObjectNotFound Exception = New-Object -TypeName 'System.ArgumentException' -ArgumentList $errMsg Message = $errMsg } Write-Error @errParams } #if no .config file(s) found. else { foreach ($file in $files) { $filesToRemoveList += $file } } } #foreach ($vmName in $Name) break } # -Name 'Nuke' { $actionString= ($MsgTable.ActionMsgRemoveDirectory) if ($PSCmdlet.ShouldProcess($VMConfigFolder, $actionString)) { try { # Reset attributes for the $VMConfigFolder directory. Set-ItemProperty -Path $VMConfigFolder -Name 'Attributes' -Value $fileAttributeNormal -Force -ErrorAction Stop } #try catch { $PSCmdlet.WriteError($_) break } #catch if ($Force) { try { Write-VMVerbose -FunctionName Remove-VMConnectConfig -Category Deleting -Message ($MsgTable.DeletingPermanentlyMsg -f $VMConfigFolder) # Reset attributes on every file to make sure that Delete() works. Get-ChildItem -Path $VMConfigFolder -Recurse:$true -Force | Set-ItemProperty -Name 'Attributes' -Value $fileAttributeNormal -Force -ErrorAction Stop ([System.IO.DirectoryInfo]$VMConfigFolder).Delete($true) } #try catch { $PSCmdlet.WriteError($_) } #catch } #if -Force else { try { Write-VMVerbose -FunctionName Remove-VMConnectConfig -Category Deleting -Message ($MsgTable.DeletingMsg -f $VMConfigFolder) $recycleOption = [Microsoft.VisualBasic.FileIO.RecycleOption]::SendToRecycleBin $null = [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($VMConfigFolder, $uiOption, $recycleOption) } #try catch { $PSCmdlet.WriteError($_) } #catch } #else } #ShouldProcess break } # -Nuke } #switch ($PSCmdlet.ParameterSetName) } #process end { if ($PSCmdlet.ParameterSetName -eq 'Nuke') { return } # Remove any duplicates. $filesToRemoveList = $filesToRemoveList | Select-Object -Unique if ($filesToRemoveList.Count -eq 0) { Write-Warning ($MsgTable.NoFilesToDelete) return } [System.String[]]$validConfigFilePathList = @() foreach ($configFile in $filesToRemoveList) { try { if ((Test-VMConnectConfig -LiteralPath $configFile -ErrorAction Stop) -eq $false) { $errMsg = ($MsgTable.InvalidConfigFileError -f $configFile) $errParams = @{ Category = $ErrorCatInvalidArgument Exception = New-Object -TypeName 'System.ArgumentException' -ArgumentList $errMsg Message = $errMsg TargetObject = $configFile } Write-Error @errParams } else { $validConfigFilePathList += $configFile } } catch { $PSCmdlet.WriteError($_) } } if ($Force) { $actionString = ($MsgTable.ActionMsgDeletePermanently) } else { $actionString = ($MsgTable.ActionMsgMoveToRecycleBin) } foreach ($file in $validConfigFilePathList) { if ($PSCmdlet.ShouldProcess($file, $actionString)) { try { if ($Force) { $recycleOption = [Microsoft.VisualBasic.FileIO.RecycleOption]::DeletePermanently $deleteVerboseMsg = ($MsgTable.DeletingPermanentlyMsg -f $file) # Reset attributes on every file to make sure that DeleteFile() works. ([System.IO.FileInfo]$file).Attributes = [System.IO.FileAttributes]::Normal } else { $recycleOption = [Microsoft.VisualBasic.FileIO.RecycleOption]::SendToRecycleBin $deleteVerboseMsg = ($MsgTable.DeletingMsg -f $file) } Write-VMVerbose -FunctionName Remove-VMConnectConfig -Category Deleting -Message $deleteVerboseMsg $null = [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file, $uiOption, $recycleOption) } #try catch { $PSCmdlet.WriteError($_) } #catch } #ShouldProcess } #foreach # Perform garbage collection. [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } #end } #function Remove-VMConnectConfig |