vbscript code to read input from text file avoidin

2019-03-04 07:07发布

问题:

I am drilling down Internet to get Vbscript code, where input is read from text file one per line and pass it to the commands in script. I am just a beginner and need help with this.

Basically I am gathering script to get pending patches of servers in our environment. The script looks like below:

    '#
    '# ServerPendingUpdates.vbs
    '#
    '# Usage: cscript ServerPendingUpdates.vbs {servername} {servername} {servername} {servername}
    '#    If no {servername} specified then 'localhost' assumed
    '#
    '# To do: Error handling
    '#
    Option Explicit
    Dim strServer        : strServer         =  GetArgValue(0,"localhost")


    '#
    '# Loop through the input parameters for each server
    '#


    Dim i
    For i = 0 To WScript.Arguments.Count - 1
        CheckServerUpdateStatus GetArgValue(i,"localhost") 'strServer
    Next

    WScript.Quit(0)

    Function CheckServerUpdateStatus( ByVal strServer )

    WScript.Echo vbCRLF & "Connecting to " & strServer & " to check software update status..."

    Dim blnRebootRequired    : blnRebootRequired     = False
    Dim blnRebootPending    : blnRebootPending     = False
    Dim objSession        : Set objSession    = CreateObject("Microsoft.Update.Session", strServer)
    Dim objUpdateSearcher     : Set objUpdateSearcher    = objSession.CreateUpdateSearcher
    Dim objSearchResult    : Set objSearchResult     = objUpdateSearcher.Search(" IsAssigned=1 and IsHidden=0 and Type='Software'")

    '#
    '#
    '#
    Dim i, objUpdate
    Dim intPendingInstalls    : intPendingInstalls     = 0

    For i = 0 To objSearchResult.Updates.Count-1
        Set objUpdate = objSearchResult.Updates.Item(I) 

        If objUpdate.IsInstalled Then
            If objUpdate.RebootRequired Then
                blnRebootPending     = True
            End If
        Else
            intPendingInstalls    = intPendingInstalls + 1
            'If objUpdate.RebootRequired Then    '### This property is FALSE before installation and only set to TRUE after installation to indicate that this patch forced a reboot.
            If objUpdate.InstallationBehavior.RebootBehavior <> 0 Then
                '# http://msdn.microsoft.com/en-us/library/aa386064%28v=VS.85%29.aspx
                '# InstallationBehavior.RebootBehavior = 0    Never reboot
                '# InstallationBehavior.RebootBehavior = 1    Must reboot
                '# InstallationBehavior.RebootBehavior = 2    Can request reboot
                blnRebootRequired     = True
            End If

        End If
    Next

    WScript.Echo strServer & " has " & intPendingInstalls & " updates pending installation"

    If blnRebootRequired Then
        WScript.Echo strServer & " WILL need to be rebooted to complete the installation of these updates."
    Else
        WScript.Echo strServer & " WILL NOT require a reboot to install these updates."
    End If


    '#
    '#
    '#
    If blnRebootPending Then
        WScript.Echo strServer & " is waiting for a REBOOT to complete a previous installation."
    End If 
End Function



'#
'#
'#
Function GetArgValue( intArgItem, strDefault )
    If WScript.Arguments.Count > intArgItem Then
        GetArgValue = WScript.Arguments.Item(intArgItem)
    Else
        GetArgValue = strDefault
    End If
End Function

Basically I am looking for a code to put in somewhere there, where the server names input that shall be manually given after command execution in CLI can be given in a text file; like a lot of servers in text file and each server is executed one per line, one at a time by the script.

Cheers!

回答1:

This allow to read from arguments collection and from standard input when - is passed as argument

Dim server

For Each server in WScript.Arguments.UnNamed
    If server="-" Then 
        Do While Not WScript.StdIn.AtEndOfStream
            WScript.Echo "Redirected: " + WScript.StdIn.ReadLine
        Loop
    Else 
        WScript.Echo "Argument: " + server
    End If
Next 

This allow to still pass arguments in the command line, and, if any of the arguments is a dash, the stantdard input is read. This will allow you to do any of the following

Usual argument pass

cscript checkServers.vbs server1 server2

Arguments and piped input

type servers.txt | cscript checkServers.vbs server1 server2 - 

Only redirected input

cscript checkServers.vbs - < servers.txt

Redirected input and arguments

< servers.txt cscript checkServers.vbs - serverx

Or any other needed combination of arguments and standard input

type servers.txt | cscript checkservers.vbs server1 server2 - aditionalServer

EDITED to answer to comments

Option Explicit
Dim strServer 

If WScript.Arguments.UnNamed.Length < 1 Then 
    CheckServerUpdateStatus "localhost"
Else
    For Each strServer in WScript.Arguments.UnNamed
        If strServer="-" Then 
            Do While Not WScript.StdIn.AtEndOfStream
                strServer = Trim(WScript.StdIn.ReadLine)
                If Len(strServer) > 0 Then CheckServerUpdateStatus strServer 
            Loop
        Else 
            CheckServerUpdateStatus strServer 
        End If
    Next 
End If
WScript.Quit(0)

Obviously, you need to maintain your CheckServerUpdateStatus function, this code only handles the parameter input.



回答2:

If you are trying to get the pending windows update installs for a bunch of computers, you can use this in Powershell:

$computers = gc text_file_of_computers.txt
ForEach ($computer in $computers) {
     ("-" * 30)+"`n" # Horizontal line

     Write-Host "Patches not yet installed for $($computer)" -f "Yellow"
     Get-Hotfix -co $computer| Where {$_.InstalledOn -eq $null}

     "`n"+("-" * 30) # Horizontal line
}

As you can see, we only show patches which have a $null value for InstalledOn, which means they have not been installed as yet.

powershell