我正在尝试使用以下脚本在Windows 7计算机上运行验证检查,但出现错误:unable to index into an object of type system.xml.xmlattributecollection
。
代码:
[cmdletBinding()] param( [Parameter(Position=0)] [ValidateScript({
Test-Path -Path $_ -PathType Leaf
})]
[string]$Config = "$PSScriptRoot\BVConfig.xml" ) BEGIN{
Function Test-Applicable{
[cmdletBinding()] param( [Parameter()] [Xml.XmlAttribute[]]$Filters , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string]$HWPlatform , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string]$HWVendor , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string]$HWModel , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string]$RegionCode , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string]$CountryCode , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string]$BuildEnv , [Parameter(ValueFromPipeLinebyPropertyName=$True)] [string[]]$Group ) Process{
$Applicable = $True
# Default
$MatchFailedOn = 'N/A'
Foreach($Filter in $Filters) {
switch -regex ($Filter.Name) {
'^HWPlatform$|^HWModel$|^BuildEnv$|^RegionCode$|^CountryCode$|^Group$' {
$ComputerValue = Get-Variable -Name "$($Filter.Name)" -ValueOnly
if(-not ($ComputerValue -match "$($Filter.Value)")) {
$Applicable = $false $MatchFailedOn = "$($Filter.Name)"
}
}
}
}
[PSCustomObject][Ordered]@{
Applicable = $Applicable MatchFailedOn = $MatchFailedOn
}
}
}
Function Get-ComputerInfo{
[cmdletBinding()] param() Process{
$OperatorMessage = "OK" #Default # Hardware information
Try {
$WMIComputer = Get-WmiObject -Class Win32_ComputerSystemProduct | Select-Object Vendor,Version,Name
$HWVendor = "$($WMIComputer.Vendor)"
$HWModel = Switch -Regex ($HWVendor){
'^Lenovo$'{
"$($WMIComputer.Version)"
}
default {
"$($WMIComputer.Name)"
}
}
}
catch {
$OperatorMessage = "ComputerSystemProduct: '$_'"
}
# Environment variables
$RegionCode = [System.Environment]::GetEnvironmentVariable("RegionCode")
$CountryCode = [System.Environment]::GetEnvironmentVariable("CountryCode")
$HWPlatform = Switch -Regex (($ENV:Computername).Substring(3,1)) {
'L|T' {
'Mobile'
}
'V' {
'Virtual'
}
'D' {
'Desktop'
}
}
# Computer object group membership
try {
$obj = new-object -com ADSystemInfo $type = $obj.gettype() $ComputerDN = $type.InvokeMember("ComputerName","GetProperty",$null,$obj,$null) $ComputerAccount = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ComputerDN") $GroupDNs = $ComputerAccount.Properties.item('MemberOf').Value $Group = $GroupDNs | %{
if($_ -match '^CN=([^,]+),'){
$Matches[1]
}
}
}
catch {
$OperatorMessage = "Computer Groups: '$_'"
}
New-Object PSObject -Property @{
HWPlatform = $HWPlatform HWVendor = $HWVendor HWModel = $HWModel RegionCode = $RegionCode CountryCode = $CountryCode Group = $Group ComputerDN = $ComputerDN OperatorMessage = $OperatorMessage
}
}
}
Function Get-ProductVersion {
[cmdletBinding()] param( [Parameter(Position=0)] [string]$Path ) $Path = [System.Environment]::ExpandEnvironmentVariables($Path)
try {
$File = Get-Item -Path $Path -ErrorAction Stop $Version = $File.VersionInfo.ProductVersion
}
catch{
$Version = $null
}
#return $Version
}
Function Get-FileOrFolder {
[cmdletBinding()] param( [Parameter(Position=0)] [string]$Path ) $Path = [System.Environment]::ExpandEnvironmentVariables($Path)
try {
$Result = Test-Path -Path $Path -ErrorAction stop
}
catch {
$Result = $false
}
#return $Result
}
}
PROCESS {
try{
# Populate variables used for Applicability checks
$ComputerInfo = Get-ComputerInfo
# Read the input file
[xml]$BVFramework = Get-Content -Path "$Config"
# Iterate over Categories in the XML
$Categories = $BVFramework.SelectNodes('/Validation/Categories/Category')
Foreach($Category in $Categories){
Describe "$($Category.Name)" {
$Rules = $Category.SelectNodes('Rules/Rule')
Foreach($Rule in $Rules){
# Is the rule applicable to this computer?
$Filters = $Rule.Applicability.Attributes
$Applicability = $ComputerInfo | Test-Applicable -Filters $Filters
if($Applicability.Applicable -eq $true) {
It "$($Rule.Title)" {
$ValidationCheck = $Rule.ValidationCheck.Attributes
$Expected = $Rule.ValidationCheck.Output.Attributes
# Compare the XML expected value to the actual
Switch -regex ("$($ValidationCheck['Category'].Value)") {
'ProductVersion' {
$ProductVersion = Get-ProductVersion -path $ValidationCheck['FilePath'].Value
# Perform the check $ProductVersion | Should Match $Expected['ExpectedOutput'].Value
}
'FileOrFolderExists' {
$FileOrFolderExists = Get-FileOrFolder -path $ValidationCheck['Path'].Value
$ExpectedOutput=Switch ($Expected['ExpectedOutput'].Value) {
'True' {
$True
}
'False' {
$False
}
default {
$Expected['ExpectedOutput'].Value
}
}
# Perform the check $FileOrFolderExists | Should be $ExpectedOutput
}
'WMIQuery' {
$SplatParams = @{
Namespace= $ValidationCheck['Namespace'].Value
Class = $ValidationCheck['Class'].Value
Property = $ValidationCheck['Property'].Value
}
if(-not([string]::IsNullOrEmpty($ValidationCheck['Filter'].Value))) {
$SplatParams.Add('Filter',$($ValidationCheck['Filter'].Value))
}
try {
$WMIResult = Get-WmiObject @SplatParams -ErrorAction Stop | Select-Object -ExpandProperty $($ValidationCheck['Property'].Value)
}
catch {
$WMIResult = $null
}
Switch ($Expected['OutputType'].Value){
'String' {
# Perform the check $WMIResult | Should Match $Expected['ExpectedOutput'].Value
}
}
}
'RegValue' {
try {
$RegResult = Get-ItemProperty -Path $($ValidationCheck['Key'].Value) -Name $($ValidationCheck['ValueName'].Value) -ErrorAction Stop | Select-Object -ExpandProperty $($ValidationCheck['ValueName'].Value)
}
catch {
$RegResult=$null
}
# Perform the check
$RegResult | Should Match $Expected['ExpectedOutput'].Value
}
'ADSpath' {
$AdsPath = [System.Environment]::ExpandEnvironmentVariables($($Expected['ExpectedOutput'].Value))
# Perform the check
$ComputerInfo.ComputerDN | Should Match $AdsPath
}
'Cmdlet' {
$Cmd = $($ValidationCheck['Command'].Value)
$Property = $($ValidationCheck['Property'].Value)
if([String]::IsNullOrEmpty($Property)) {
$Result = &"$cmd"
}
else {
$Result = &"$cmd | Select-Object -ExpandProperty $Property"
}
$ExpectedOutput=Switch ($Expected['ExpectedOutput'].Value) {
'True' {
$True
}
'False' {
$False
}
default {
$Expected['ExpectedOutput'].Value
}
}
$Result | Should match $ExpectedOutput
}
}
}
#It
}
else {
Write-Verbose "$($Rule.Title) was not applicable - $($Applicability.MatchFailedOn)"
}
}
#Rule
}
#describe
}
#Categories
}
catch {
Throw "Error '$_'"
}
}