Powershell编码将值传递给WmiMethod

时间:2014-01-12 16:09:49

标签: powershell wmi bios

所以,我一直在编写HP Bios的一些任务。有一个名为HPBIOS_BIOSSettingInterface的Wmi命名空间。它基本上有一个方法SetBIOSSetting(“属性”,“值”,“CurrentSetupPassword”)。较旧的HP系统仅支持KBD编码,我编写了一个函数来编码具有KDB值的字符串,可以在此处找到:http://thomas-malkewitz.webnode.com/news/convert-tokbdstring/,当使用此编码设置设置密码值时,它可以工作,但是使用新的HP ,它只支持UTF-16(我无法找到它的大或小,但已经尝试过两者)。这样做时我一直都会遇到错误。所以,我的问题是,我如何编码字符串值并将其传递给此方法。我无法想象我的生活。这是我的功能:

<#
.Synopsis
    Sets the Setup Password on an HP Bios.
.DESCRIPTION
    This function can be used to set a password on the Bios, it can also be used to clear the password, the current password is needed to change the value.
    If a new value is being set, and not cleared, it must be between 8 and 30 characters.
.EXAMPLE
    Set-HpSetupPassword -NewSetupPassword "MyNewPassword"
.EXAMPLE
    Set-HpSetupPassword -ComputerName "mycomputer.mydomain.org" -NewSetupPassword " " -CurrentSetupPassword "MyCurrentPassword"
.EXAMPLE
    Set-HpSetupPassword -NewSetupPassword "MyNewSetupPassword" -CurrentSetupPassword "MyCurrentPassword"
.LINKS
    https://github.com/necromorph1024/HPTpmAndBitLocker
#>
function Set-HpSetupPassword
{
    [CmdletBinding()]
    [OutputType([void])]
    Param
    (
        # ComputerName, Type string, System to set Bios Setup Password.
        [Parameter(Mandatory=$false,
                   Position=0)]
        [string]
        $ComputerName=$env:COMPUTERNAME,

        # NewSetupPassword, Type string, The value of the password to be set.  The password can be cleared by using a space surrounded by double quotes, IE: " ".
        [Parameter(Mandatory=$true,
                   Position=1)]
        [string]
        $NewSetupPassword,

        # CurrentSetupPassword, Type string, The value of the current setup password.
        [Parameter(Mandatory=$false,
                   Position=2)]
        [AllowEmptyString()]
        [string]
        $CurrentSetupPassword
    )

    Begin
    {
        if (!(Test-Connection -ComputerName $ComputerName -Quiet -Count 2)) 
        {
            throw "Unable to connect to $ComputerName.  Please ensure the system is available."
        }

        try
        {
            $manufacturer = Get-WmiObject -Class Win32_ComputerSystem -Namespace "root\CIMV2" -Property "Manufacturer" -ComputerName $ComputerName -ErrorAction Stop
            if ($manufacturer.Manufacturer -ne "Hewlett-Packard")
            {
                throw "Computer Manufacturer is not of type Hewlett-Packard.  This cmdlet can only be used on Hewlett-Packard systems."
            }
        }
        catch
        {
            throw "Unable to connect to the Win32_ComputerSystem WMI Namespace, verify the system is avaialbe and you have the permissions to access the namespace."
        }
    }
    Process
    {
        if (-not([String]::IsNullOrWhiteSpace($NewSetupPassword)))
        {
            if (($NewSetupPassword.Length -lt 8) -or ($NewSetupPassword.Length -gt 30))
            {
                throw "The Password Values must be be between 8 and 30 characters if not clearing the password."
            }
        }

        $hpBios = Get-WmiObject -Class HP_BiosSetting -Namespace "root\HP\InstrumentedBIOS" -ComputerName $ComputerName -ErrorAction Stop
        $hpBiosSettings = Get-WmiObject -Class HPBIOS_BIOSSettingInterface -Namespace "root\HP\InstrumentedBIOS" -ComputerName $ComputerName -ErrorAction stop

        if (($hpBios | Where-Object { $_.Name -eq "Setup Password"}).SupportedEncoding -eq "kbd")
        {
            if (-not([String]::IsNullOrEmpty($NewSetupPassword)))
            {
                $NewSetupPassword="<kbd/>"+(Convert-ToKbdString -UTF16String $NewSetupPassword)
            }
            if (-not([String]::IsNullOrEmpty($CurrentSetupPassword)))
            {
                $CurrentSetupPassword="<kbd/>"+(Convert-ToKbdString -UTF16String $CurrentSetupPassword)
            }
        }

        $hpBiosSettings.SetBIOSSetting("Setup Password",$NewSetupPassword,$CurrentSetupPassword)
    }
}

它保持返回6,这是拒绝访问,这是我用旧的BIOS生成的,直到我创建了Convert-KbdString方法。我知道使用的密码是正确的。但我不知道发送给WmiMethod的编码是什么。谢谢你的帮助

这是GitHub回购:https://github.com/necromorph1024/HpTpmAndBitLocker

3 个答案:

答案 0 :(得分:1)

根据{{​​1}}类的文档,

.NET字符串采用Unicode编码。

http://msdn.microsoft.com/en-us/library/system.string(v=vs.110).aspx

答案 1 :(得分:0)

我现在甚至都在问这个问题我觉得很蠢。我查看了自己的方法,字符串需要用编码类型标记。我知道这个,这就是为什么我将<kbd/>附加到字符串,如果它支持该编码类型。因此,<utf-16/>标记只需要附加到字符串的开头。天哪,对不起,我可能已经浪费了!

答案 2 :(得分:0)

你如何使用Foreach($ computer in $ computername)循环运行?将会放置哪些内容并且会有任何特殊语法?