У меня проблемы с кодом PowerShell, который не работает должным образом в версии 2 - PullRequest
0 голосов
/ 18 апреля 2019

Мы пытаемся обновить наш BIOS в последовательности задач, и у меня есть скрипт от Lenovo, который отлично работает в Windows 10 и PowerShell v5.Тем не менее, он не работает должным образом в Windows 7 с PowerShell v2.Мы не можем выполнить обновление до v5 на компьютерах с Windows 7.

Сценарий считывает XML-файл, который я экспортировал из SCCM, и сопоставляет соответствующий пакет BIOS, загружает и запускает его.

Сценарий выглядит так:

[xml]$Packages = Get-Content BIOSPackages.xml

# Environment variable call for task sequence only
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment

$BIOS = (Get-WmiObject -Namespace root\cimv2 -Class Win32_BIOS).SMBIOSBIOSVersion.Substring(0,4)

$ns = New-Object Xml.XmlNamespaceManager $Packages.NameTable
$ns.AddNamespace("def", "http://schemas.microsoft.com/powershell/2004/04")

$Xpathqry = "/def:Objs/def:Obj//def:MS[contains(.,`"$BIOS`")]"

$Package = ($Packages.SelectNodes($xpathqry,$ns))
$PackageID = $Package.SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
$tsenv.Value('OSDDownloadDownloadPackages') = $PackageID.InnerXML

и он не срабатывает:

$PackageID = $Package.SelectNodes('def:S[contains(@N,"PackageID")]',$ns)

Я пытался выдумать его в течение дня, и я просто бью стену.

Я получаю следующую ошибку:

Method invocation failed because [System.Xml.XPathNodeList] doesn't contain a
method named 'SelectNodes'.
At C:\_SMSTaskSequence\Packages\NC1002CB\Get-BIOSPackages.ps1:17 char:38
+ $PackageID = $Package.SelectNodes <<<< ('def:S[contains(@N,"PackageID")]',$ns)
    + CategoryInfo          : InvalidOperation: (SelectNodes:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

1 Ответ

1 голос
/ 18 апреля 2019

Сообщение об ошибке на самом деле довольно ясно. $Packages.SelectNodes() возвращает коллекцию XPathNodeList. В последующем утверждении вы пытаетесь вызвать метод SelectNodes() для этой коллекции, когда у коллекции нет такого метода. Что является причиной ошибки.

Причина, по которой код работает в PowerShell v5, заключается в том, что Microsoft представила новую функцию под названием «перечисление членов» в PowerShell v3, которая автоматически передает вызовы несуществующим элементам (свойствам и методам) коллекции. к элементам коллекции. В вашем случае, поскольку в коллекции $Package нет метода SelectNodes(), вызов $Package.SelectNodes() вызовет ошибку в PowerShell v2 и более ранних версиях и вызовет SelectNodes() для элементов из $package в PowerShell v3 и новее.

Существуют различные способы решения проблемы, например,

  • Обновите PowerShell до версии 3 или новее на компьютерах с Windows 7. Да, я видел, что вы сказали, что не можете обновить машины с Windows 7, но на самом деле это предпочтительное решение.

  • Ограничить результат $Packages.SelectNodes() одним элементом:

    $Package = $Packages.SelectNodes($xpathqry, $ns) |
               Select-Object -First 1
    
  • Используйте только первый элемент $Packages в следующей записи:

    $PackageID = $Package[0].SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
    
  • Вызов SelectNodes() для каждого элемента $Package:

    $PackageID = $Package | ForEach-Obejct {
        $_.SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...