Public/Reset-VMConnectConfig.ps1
#.ExternalHelp VMConnectConfig-help.xml function Reset-VMConnectConfig { [CmdletBinding(ConfirmImpact = 'Medium', DefaultParameterSetName = 'Name', HelpURI='https://thegraffix.github.io/VMConnectConfig/reset-vmconnectconfig.html', SupportsShouldProcess)] [Alias('rsvmc')] [OutputType([System.Management.Automation.PSCustomObject])] param ( [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 = 'LiteralPath', ValueFromPipelineByPropertyName)] [Alias('FullName')] [ValidateNotNullOrEmpty()] [System.String[]]$LiteralPath, [Parameter(Mandatory, ParameterSetName = 'Name', Position = 0, ValueFromPipeline)] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [System.String[]]$Name, [switch]$PassThru, [Parameter(Mandatory, ParameterSetName = 'Path')] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [System.String[]]$Path ) 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'} [System.String[]]$configFilePathList = @() } #begin process { if ($PSCmdlet.ParameterSetName -notlike '*Path') { $null = Test-VMConfigFolder $allConfigFiles = Get-AllConfigFiles } switch ($PSCmdlet.ParameterSetName) { '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) { $configFilePathList += $file } } } #foreach $vmGuid break } # -Id 'InputObject' { foreach ($file in $InputObject.Path) { $configFilePathList += $file } break } # -InputObject 'LiteralPath' { foreach ($literalItem in $LiteralPath) { $literalPathError = $null $resolvedLiteralPaths = @() $resolvedLiteralPaths = [System.String[]]((Resolve-Path -LiteralPath $literalItem -ErrorVariable 'literalPathError').Path | Where-Object {[System.IO.File]::Exists($_)}) if ((($resolvedLiteralPaths.Count -eq 0) -or ([System.String]::IsNullOrEmpty($resolvedLiteralPaths))) -and [System.String]::IsNullOrEmpty($literalPathError)) { # Output an error message when Resolve-Path returns 0 items and doesn't output an error message. $resolvedLiteralItemPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($literalItem) $errMsg = ($MsgTable.ConfigFileNotFoundPathError -f $resolvedLiteralItemPath) $errParams = @{ Category = $ErrorCatObjectNotFound Exception = New-Object -TypeName 'System.IO.FileNotFoundException' -ArgumentList $errMsg, $resolvedLiteralItemPath Message = $errMsg TargetObject = $resolvedLiteralItemPath } Write-Error @errParams } #if no .config file(s) found. else { foreach ($resolvedLiteralPath in $resolvedLiteralPaths) { $configFilePathList += $resolvedLiteralPath } } } #foreach $literalItem break } # -LiteralPath '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) { $configFilePathList += $file } } } #foreach $vmName break } # -Name 'Path' { foreach ($item in $Path) { $pathError = $null $resolvedPaths = @() $resolvedPaths = [System.String[]]((Resolve-Path -Path $item -ErrorVariable 'pathError').Path | Where-Object {[System.IO.File]::Exists($_)}) if ((($resolvedPaths.Count -eq 0) -or ([System.String]::IsNullOrEmpty($resolvedPaths))) -and ([System.String]::IsNullOrEmpty($pathError))) { # Output an error message when Resolve-Path returns 0 items and doesn't output an error message. $resolvedItemPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($item) $errMsg = ($MsgTable.ConfigFileNotFoundPathError -f $resolvedItemPath) $errParams = @{ Category = $ErrorCatObjectNotFound Exception = New-Object -TypeName 'System.IO.FileNotFoundException' -ArgumentList $errMsg, $resolvedItemPath Message = $errMsg TargetObject = $resolvedItemPath } Write-Error @errParams } #if no .config file(s) found. else { foreach ($resolvedPath in $resolvedPaths) { $configFilePathList += $resolvedPath } } } #foreach $item break } # -Path } #switch ($PSCmdlet.ParameterSetName) } #process end { $configFilePathList = $configFilePathList | Select-Object -Unique [System.String[]]$passThruList = @() foreach ($configFile in $configFilePathList) { if ((Test-VMConnectConfig -LiteralPath $configFile -ErrorAction SilentlyContinue) -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 continue } try { $xmlFile = New-Object -TypeName 'System.Xml.XmlDocument' $xmlFile.Load($configFile) switch ($xmlFile.SelectNodes($XPath).Count) { 15 {$configFileType = 'Legacy'; break} 16 {$configFileType = 'Modern'; break} 17 {$configFileType = 'WebAuthn'; break} } $vmId = $null $vmId = ($configFile | Select-String -Pattern $GuidRegexPattern).Matches.Value [System.String]$vmName = $xmlFile.SelectSingleNode($VMNameXPath).value [System.String]$vmServerName = $xmlFile.SelectSingleNode($VMServerNameXPath).value } #try catch { $PSCmdlet.WriteError($_) continue } #catch # Prevent $vmId from being part of the $actionString if $vmId is $null or an empty string. $actionVmId = $null if ([System.String]::IsNullOrEmpty($vmId) -eq $false) { $actionVmId = " ($vmid)" } $actionString = ($MsgTable.ActionMsgResetVmConfigFile -f $vmName, $actionVmId) if ($PSCmdlet.ShouldProcess($configFile, $actionString)) { $newVmConfigProps = @{ Name = $vmName Path = $configFile VMServerName = $vmServerName ConfigFileType = $configFileType Force = $true Verbose = $false Confirm = $false PassThru = $false } try { Write-VMVerbose -FunctionName Reset-VMConnectConfig -Category Writing -Message ($MsgTable.ResetVmConfigFileMsg -f $configFile) $null = New-VMConnectConfig @newVmConfigProps if ($PassThru) { $passThruList += $configFile } #if -PassThru } #try catch { $PSCmdlet.WriteError($_) continue } #catch } #ShouldProcess } #foreach $configFile if ($passThruList.Count -gt 0) { Get-VMConnectConfig -LiteralPath $passThruList } # Perform garbage collection. [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } #end } #function Reset-VMConnectConfig |