powershell修补程序脚本无法运行

时间:2017-11-13 16:58:16

标签: powershell

我一直试图找到一种远程方法,从一个jumphost,验证已经安装了一个补丁。我正在使用我在Microsoft页面上找到的脚本,但它会发回错误。我一直试图找到一个解决方案,没有运气,任何人都可以帮助我.---更新

这是我得到的错误:

You cannot call a method on a null-valued expression.
At C:\Temp\HOTFIX.ps1:53 char:18
+ $Sheet.Cells.Item <<<< ($intRow,2)  ="status" 
    + CategoryInfo          : InvalidOperation: (Item:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\Temp\HOTFIX.ps1:54 char:18
+ $Sheet.Cells.Item <<<< ($intRow,3)  ="Patch status" 
    + CategoryInfo          : InvalidOperation: (Item:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\Temp\HOTFIX.ps1:55 char:18
+ $Sheet.Cells.Item <<<< ($intRow,4)  ="OS" 
    + CategoryInfo          : InvalidOperation: (Item:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

脚本:

  #Check for a specific patch on remote PCs v1.2
# Tom Latham 04/02/2010
#
# Added v1.1: Error messaages
# Added v1.2: GUI Inputs

# Function to open file dialog box and select a file
Function Get-FileName($initialDirectory)
{   
    [void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")

    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $initialDirectory
    $OpenFileDialog.filter = "Text Files (*.txt)| *.txt" # Set the file types visible to dialog

    $OpenFileDialog.ShowDialog() | Out-Null
    $OpenFileDialog.filename
}

# Function to prompt user for kb number
Function Get-Input
{
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

    $objForm = New-Object System.Windows.Forms.Form 
    $objForm.Text = "Enter KB Number"
    $objForm.Size = New-Object System.Drawing.Size(300,200) 
    $objForm.StartPosition = "CenterScreen"

    $objForm.KeyPreview = $True
    $objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
        {$x=$objTextBox.Text;$objForm.Close()}})
    $objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
        {$objForm.Close()}})

    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Size(75,120)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = "OK"
    $OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()})
    $objForm.Controls.Add($OKButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Size(150,120)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.Add_Click({$objForm.Close()})
    $objForm.Controls.Add($CancelButton)

    $objLabel = New-Object System.Windows.Forms.Label
    $objLabel.Location = New-Object System.Drawing.Size(10,20) 
    $objLabel.Size = New-Object System.Drawing.Size(280,20) 
    $objLabel.Text = "Please enter the KB number below (kbxxxxxx):"
    $objForm.Controls.Add($objLabel) 

    $objTextBox = New-Object System.Windows.Forms.TextBox 
    $objTextBox.Location = New-Object System.Drawing.Size(10,40) 
    $objTextBox.Size = New-Object System.Drawing.Size(260,20) 
    $objForm.Controls.Add($objTextBox) 

    $objForm.Topmost = $True

    $objForm.Add_Shown({$objForm.Activate()})
    [void] $objForm.ShowDialog()

    $x
}

# Main Program --------------------------------------

# Do not display errors
$erroractionpreference = "SilentlyContinue"

# Clear screen
clear-host

# Store user credentials
$cred = get-credential

# Supply text file of all PCs to be checked and KB number to search for

# Run Open File Dialog
$filename = Get-FileName -initialDirectory "c:"

# Get path of file to be used in storing results
$path = split-path $filename

# If kbresults.txt exists, delete it
if (test-path $path\kbresults.txt)
{ remove-item $path\kbresults.txt }

# Get kb number
$kb = Get-Input

# Extract content from filename object
$computernames = get-content $filename

# For each computer in list
foreach ($computer in $computernames)
{
    # Set query string to query ping status
    $strQuery = "select * from win32_pingstatus where address = '" + $computer + "'"

    # Get WMI object using query
    $wmi = gwmi -query $strquery

    # If machine pings (status = 0)
    if ($wmi.statuscode -eq 0)
    {

        # Get WMI object on computer where hotfixid equals our kb number
        # Use stored user credentials
        $checkkb = gwmi win32_QuickFixEngineering -computer $computer -credential $cred | where {$_.hotfixid -eq $kb} | select-object hotfixid, description

        switch -regex ($Error[ 0 ].Exception)
        {
            "The RPC server is unavailable"
            {
                write-host -f blue $computer "`t" "RPC Unavailable on $computer" "`r"
                "$computer `t RPC Unavailable." | out-file $path\kbresults.txt -append
                continue
            }
            "Access denied"
            {
                write-host -f blue $computer "`t" "Access Denied" "`r"
                "$computer `t Access Denied." | out-file $path\kbresults.txt -append
                continue
            }
            "Access is denied"
            {
                write-host -f blue $computer "`t" "Access Denied" "`r"
                "$computer `t Access Denied." | out-file $path\kbresults.txt -append
                continue
            }
            # No error -> record our info!
            $null
            {
                # If kb numbers match
                if ($checkkb.hotfixid -eq $kb)
                {
                    # Patch is installed. Test reboot status.

                    # Connect to remote registry hive (HKLM)
                    $regHive = [Microsoft.Win32.RegistryHive]"LocalMachine"; 
                    $regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$computer); 

                    # Set subkey to 'UpdateExeVolatile', the existence of which show reboot pending status
                    $subKey = $regKey.OpenSubKey("SOFTWARE\Microsoft\Updates\UpdateExeVolatile"); 
                    # If subkey is not found
                    if (!$subKey) 
                    {
                        # Patch is installed
                        write-host -f green $computer "`t" $checkkb.description "`r"
                        "$computer `t Installed." | out-file $path\kbresults.txt -append
                    }
                    else 
                    {
                        # Patch installed. Reboot required.
                        write-host -f green $computer "`t" $checkkb.description "`r"
                        "$computer `t Reboot Required" | out-file $path\kbresults.txt -append
                    }
                }
                else
                {
                    # Patch is not installed.
                    write-host -f red $computer "`t" "Not Found" "`r"
                    "$computer `t Not Installed." | out-file $path\kbresults.txt -append
                }            
             }
        }

        $Error.clear()
    }
    else 
    { 
        # Machine doesn't ping. Write to screen and append to results file.
        write-host $computer "`t" "Cannot ping." "`r"
        "$computer `t Ping failed." | out-file $path\kbresults.txt -append
    }
}

0 个答案:

没有答案