Question

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!

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top