Public/Test-VMConnectConfig.ps1
#.ExternalHelp VMConnectConfig-help.xml function Test-VMConnectConfig { [CmdletBinding(DefaultParameterSetName = 'Path', HelpURI='https://thegraffix.github.io/VMConnectConfig/test-vmconnectconfig.html')] [Alias('tvmc')] [OutputType([System.Boolean])] param ( [Parameter(Mandatory, ParameterSetName = 'LiteralPath', ValueFromPipelineByPropertyName)] [Alias('FullName')] [ValidateNotNullOrEmpty()] [System.String[]]$LiteralPath, [Parameter(Mandatory, ParameterSetName = 'Path', Position = 0)] [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'} } #begin process { [System.String[]]$configFilePathList = @() switch ($PSCmdlet.ParameterSetName) { '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) Write-VMVerbose -FunctionName Test-VMConnectConfig -Category Error -Message ($MsgTable.ConfigFileNotFoundPathError -f $resolvedLiteralItemPath) Write-Output $false } elseif ([System.String]::IsNullOrEmpty($resolvedLiteralpaths)) { Write-Output $false } else { foreach ($resolvedLiteralPath in $resolvedLiteralPaths) { $configFilePathList += $resolvedLiteralPath } } } #foreach break } # -LiteralPath '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) Write-VMVerbose -FunctionName Test-VMConnectConfig -Category Error -Message ($MsgTable.ConfigFileNotFoundPathError -f $resolvedItemPath) Write-Output $false } elseif (($resolvedPaths.Count -eq 0) -or ([System.String]::IsNullOrEmpty($resolvedPaths))) { Write-Output $false } else { $resolvedPaths | ForEach-Object {$configFilePathList += $_} } } #foreach break } # -Path } #switch ($PSCmdlet.ParameterSetName) foreach ($file in $configFilePathList) { $xmlFile = $null $xmlSchema = $null $xmlStrReader = $null $xmlNodeList = $null $verboseErrorMsg = $null $configFileIsValid = $false if ([System.IO.Path]::GetExtension($file) -ne '.config') { Write-VMVerbose -FunctionName Test-VMConnectConfig -Category Error -Message ($MsgTable.InvalidConfigFileExtensionError -f $file) Write-Output $false continue } try { $xmlFile = New-Object -TypeName 'System.Xml.XmlDocument' # Test if $file is a well-formed XML document. Write-VMVerbose -FunctionName Test-VMConnectConfig -Category Reading -Message ($MsgTable.LoadingFileMsg -f $file) $xmlFile.Load($file) # Validate $file against XML schema. Write-VMVerbose -FunctionName Test-VMConnectConfig -Category Testing -Message ($MsgTable.XmlSchemaValidatingFileMsg -f $file) $xmlStrReader = New-Object -TypeName 'System.IO.StringReader' -ArgumentList $VMConnectConfigXmlSchema $xmlSchema = [System.Xml.Schema.XmlSchema]::Read($xmlStrReader, $null) $null = $xmlFile.Schemas.Add($xmlSchema) $xmlFile.Validate($null) $xmlNodeList = ($xmlFile.SelectNodes($XPath)).Name $diffObj = $null if ($xmlNodeList.Count -eq 15) { $diffObj = $LegacySettingsList } elseif ($xmlNodeList.Count -eq 16) { $diffObj = $ModernSettingsList } elseif ($xmlNodeList.Count -eq 17) { $diffObj = $WebAuthnSettingsList } if ($null -ne (Compare-Object -ReferenceObject $xmlNodeList -DifferenceObject $diffObj)) { $verboseErrorMsg = ($MsgTable.InvalidXmlElementError -f $file) } else { $configFileIsValid = $true } } #try catch [System.IO.FileNotFoundException], [System.IO.DirectoryNotFoundException] { $errMsg = ($MsgTable.PathNotFoundError -f $file) $errParams = @{ Category = $ErrorCatObjectNotFound Exception = New-Object -TypeName 'System.IO.FileNotFoundException' -ArgumentList $errMsg, $file Message = $errMsg TargetObject = $file } Write-Error @errParams } catch [System.Xml.XmlException] { $verboseErrorMsg = ($MsgTable.InvalidXmlFileError -f $file) } catch [System.Xml.Schema.XmlSchemaValidationException] { $verboseErrorMsg = ($MsgTable.InvalidConfigFileError -f $file) } catch { $PSCmdlet.WriteError($_) } #catch finally { if ($xmlStrReader) { $xmlStrReader.Close() } if ($verboseErrorMsg) { Write-VMVerbose -FunctionName Test-VMConnectConfig -Category Error -Message $verboseErrorMsg } Write-Output $configFileIsValid } #finally } #foreach $file } #process end { # Perform garbage collection. [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } #end } #function Test-VmConnectConfig |