PowerShell在修改密码时遇到的问题

后端开发 2026-07-12

我有一个PowerShell脚本,用来修改本地管理员密码,并将结果输出为CSV。

我遇到了如下错误信息:

Export-Csv:无法将参数 'InputObject' 绑定,因为它为null。

在G:\AdminScript\changeLocalAdminPassword2.ps1:60字符:1

位于G:\AdminScript\changeLocalAdminPassword2.ps1:60字符:1

我的脚本

$computers       = Get-Content "g:\computers.txt"

function Get-RandomPassword {
    param (
        [Parameter(Mandatory)]
        [int] $length,
        [int] $amountOfNonAlphanumeric = 1
    )
    Add-Type -AssemblyName 'System.Web'
    [System.Web.Security.Membership]::GeneratePassword($length, $amountOfNonAlphanumeric)
}

$passwordResetReport = 
foreach ($Computer in $Computers) {

    $newPassword  = Get-RandomPassword 12

    if ((Test-Connection -ComputerName $Computer -Count 1 -ErrorAction SilentlyContinue -ErrorVariable TestError)) {
        $invokeError = $null
        try {
            $account = [ADSI]("WinNT://$Computer/Administrator")
            $account.psbase.invoke("setpassword", $newPassword)
            $invokeError = "Administrator Password changed successfully"
        }
        catch {
            $invokeError = $error[0].Exception.Message
        }

        if($invokeError -match 'successfully'){
            [pscustomobject]@{
                ComputerName         = $Computer
                IsOnline             = $Isonline
                PasswordChangeStatus = $Status
                DetailedStatus       = $invokeError
                NewCredentials       = $newPassword
            }
        }
        else{
            [pscustomobject]@{
                ComputerName         = $Computer
                IsOnline             = "ONLINE"
                PasswordChangeStatus = $Status
                DetailedStatus       = $invokeError
                NewCredentials       = "-"
            }    
        }
    } 
    else { 
        [pscustomobject]@{
            ComputerName         = $Computer
            IsOnline             = "OFFLINE"
            PasswordChangeStatus = "Failed"
            Status       = $testError -join ""
            PASSWORD       = "-"
        } 
    }
}

$passwordResetReport|
Export-Csv "g:\password.csv" -NoTypeInformation

解决方案

问题在于 $account.psbase.invoke("setpassword", $newPassword) 返回 $null,因为你没有对其进行赋值或置空。$account 是一个 DirectoryEntry 对象,其 .Invoke() method 的返回类型是 object?。当那个 $null 遇到 Export-Csv 时,该cmdlet不知道该如何处理。

此外,你的输出对象属性不一致,而且你还引用了未定义的变量 $Status

也没必要把结果存储起来;使用 ForEach-Object 命令,并把结果直接通过管道传给 Export-Csv

可以试试下面这样:

$inFile = "g:\computers.txt"
$outFile = "g:\password.csv"

Function Get-RandomPassword {
    Param (
        [Parameter(Mandatory)]
        [int]$Length,
        [int]$AmountOfNonAlphanumeric = 1
    )
    Add-Type -AssemblyName 'System.Web'
    [System.Web.Security.Membership]::GeneratePassword($Length, $AmountOfNonAlphanumeric)
}

Get-Content -Path $inFile -ErrorAction Stop | ForEach-Object {
    $computer = $_
    Write-Host "Processing $($computer)"
    $result = [PSCustomObject]@{
        ComputerName   = $computer
        Status         = 'OFFLINE'
        Error          = $null
        NewCredentials = $null
    }
    If ((Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue -ErrorVariable testError)) {
        Try {
            $newPassword = Get-RandomPassword -Length 12
            $account = [ADSI]("WinNT://$($computer)/Administrator")
            [void]$account.psbase.Invoke('setpassword', $newPassword)

            $result.Status = 'OK'
            $result.NewCredentials = $newPassword
        } Catch {
            $result.Status = 'ERROR'
            $result.Error = $_.Exception.Message
        }
    } Else {
        # If Count in Test-Connection will always remain at 1, a simple "$result.Error = $testError[0].Exception.Message" will do.
        # This version will also handle multiple pings:
        $result.Error = ($testError | ForEach-Object {$_.Exception.Message} | Select-Object -Unique) -join '; '
    }
    $result
} | Export-Csv -Path $outFile -NoTypeInformation
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章