Link to home
Start Free TrialLog in
Avatar of Dhiraj Mutha
Dhiraj MuthaFlag for United States of America

asked on

Powershell to read text file

We use a different method to deploy patches. Everything is going well, I just need to audit the patches whether they are installed or not, so during the installation of the these patches it creates 2 files in C:\Installs\Patches folder. The file names of these files will be like this.

KBxxxxxx.RTInst.txt
KBxxxxxx.Verify.txt
KByyyyyy.RTInst.txt
KByyyyyy.Verify.txt

What I am looking is a PowerShell script, that will read the last 3rd line of KBxxxxxx.Verify.txt file.

I will provide a computers.txt with all hostnames and modules.txt with the KB article numbers, then the script should check whether the KBxxxxxx.RTInst.txt exists, if yes then should go ahead and check for KBxxxxxx.Verify.txt exists, if yes then it should read the last 3rd line of it and if the line says “Hotfix successfully installed” then write the output to a text or csv file in this fashion.

HOSTNAME,KBxxxxxx,Success
HOSTNAME,KByyyyyy,Fail
HOSTNAME,KBzzzzzz,NoRTInst
HOSTNAMe,KBaaaaaa,NoVerify
Avatar of soostibi
soostibi
Flag of Hungary image

Could you attach a sample of the KB....txt files?
Avatar of Dhiraj Mutha

ASKER

It has some data stating whether the patch is installed or not, and the last 3rd line says 'Hotfix is sucessfully installed' or it will say 'Hotfix not installed'.
Try this. I assume, that the modules.txt include only the numbers:

111111
222222

Not:

KB111111
KB222222

If it unclude the 'KB', then tell me, I'll change the script. I also assume, that the path can be accessed through the admin shares.
You can export the report to csv by adding to the last line:
    | export-csv c:\yourpath\pathreport.csv -notypeinformation
$modules = Get-Content C:\yourpath\modules.txt
$computers = Get-Content C:\yourpath\computers.txt
$root =  "C$\Installs\Patches"

$computers | %{
    $comp = $_
    $modules | %{
        $instexists = test-path "\\$comp\$root\kb$_.RTInst.txt" 
        $verifyexists = test-path "\\$comp\$root\kb$_.Verify.txt" 
        if($verifyexists){
            $text = Get-Content "\\$comp\$root\kb$_.Verify.txt" -ReadCount 0
            if($text[-3] -eq "Hotfix successfully installed"){$success = "Success"}
            else{$success = "Fail"}
        }
        New-Object -TypeName PSObject -Property @{
            Hostname = $comp
            KBNumber = "KB$_"
            Result = if(!$instexists){"NoRTInst"}elseif(!$verifyexists){"NoVerify"}else{$success}
        }
    }
} | Select-Object hostname, KBNumber, Result

Open in new window

yes it includes KB.
Try this:
$modules = Get-Content C:\yourpath\modules.txt  
$computers = Get-Content C:\yourpath\computers.txt  
$root =  "C$\Installs\Patches"  
  
$computers | %{  
    $comp = $_  
    $modules | %{  
        $instexists = test-path "\\$comp\$root\$_.RTInst.txt"   
        $verifyexists = test-path "\\$comp\$root\$_.Verify.txt"   
        if($verifyexists){  
            $text = Get-Content "\\$comp\$root\$_.Verify.txt" -ReadCount 0  
            if($text[-3] -eq "Hotfix successfully installed"){$success = "Success"}  
            else{$success = "Fail"}  
        }  
        New-Object -TypeName PSObject -Property @{  
            Hostname = $comp  
            KBNumber = $_  
            Result = if(!$instexists){"NoRTInst"}elseif(!$verifyexists){"NoVerify"}else{$success}  
        }  
    }  
} | Select-Object hostname, KBNumber, Result

Open in new window

Ok. Thanks. I will update you on monday.
Its giving a error:

New-Object : A parameter cannot be found that matches parameter name 'Property'.
At C:\Documents and Settings\a012245-a\Desktop\ModuleAudit-Win7\ModuleAuditWin7.ps1:15 char:48
+         New-Object -TypeName PSObject -Property  <<<< @{
New-Object : A parameter cannot be found that matches parameter name 'Property'.
At C:\Documents and Settings\a012245-a\Desktop\ModuleAudit-Win7\ModuleAuditWin7.ps1:15 char:48
+         New-Object -TypeName PSObject -Property  <<<< @{


For the below attached code.
$modules = Get-Content .\modules.txt  
$computers = Get-Content .\devices.txt  
$root =  "C$\Installs\Logs"  
  
$computers | %{  
    $comp = $_  
    $modules | %{  
        $instexists = test-path "\\$comp\$root\$_.RTInst.txt"   
        $verifyexists = test-path "\\$comp\$root\$_.Verify.txt"   
        if($verifyexists){  
            $text = Get-Content "\\$comp\$root\$_.Verify.txt" -ReadCount 0  
            if($text[-3] -eq "Hotfix successfully installed"){$success = "Success"}  
            else{$success = "Fail"}  
        }  
        New-Object -TypeName PSObject -Property @{  
            Hostname = $comp  
            KBNumber = $_  
            Result = if(!$instexists){"NoRTInst"}elseif(!$verifyexists){"NoVerify"}else{$success}  
        }  
    }  
} | Select-Object hostname, KBNumber, Result |export-csv .\pathreport.csv -notypeinformation

Open in new window

Strange. New-Object is a built in cmdlet, and has a Property parameter...
does it create any issue if powershell is version 1?
Yes, it can be the problem. Can you upgrade to v2.0?
If not, maybe this will work:
$modules = Get-Content .\modules.txt    
$computers = Get-Content .\devices.txt    
$root =  "C$\Installs\Logs"    
    
$computers | %{    
    $comp = $_    
    $modules | %{    
        $instexists = test-path "\\$comp\$root\$_.RTInst.txt"     
        $verifyexists = test-path "\\$comp\$root\$_.Verify.txt"     
        if($verifyexists){    
            $text = Get-Content "\\$comp\$root\$_.Verify.txt" -ReadCount 0    
            if($text[-3] -eq "Hotfix successfully installed"){$success = "Success"}    
            else{$success = "Fail"}    
        }    
        $mod = $_
        "" | Select-Object -Property @{    
            n="Hostname"; e={$comp}},
            @{n="KBNumber"; e={ = $mod}},
            @{n="Result";e = {if(!$instexists){"NoRTInst"}elseif(!$verifyexists){"NoVerify"}else{$success}}
        }    
    }    
} | Select-Object hostname, KBNumber, Result |export-csv .\pathreport.csv -notypeinformation

Open in new window

Ok i will try this tomorrow and update you.
Getting this error.

Select-Object : The term '=' is not recognized as a cmdlet, function, operable program, or script file. Verify the term
 and try again.
At C:\Documents and Settings\a012245-a\Desktop\ModuleAudit-Win7\ModuleAuditWin7.ps1:16 char:27
+         "" | Select-Object  <<<< -Property @{
Select-Object : The term '=' is not recognized as a cmdlet, function, operable program, or script file. Verify the term
 and try again.
At C:\Documents and Settings\a012245-a\Desktop\ModuleAudit-Win7\ModuleAuditWin7.ps1:16 char:27
+         "" | Select-Object  <<<< -Property @{
Its working with v2.0

But the output is this:

"Hostname","KBNumber","Result"
"Computername",,"NoRTIInst"
"Computername",,"NoRTIInst"

This means its not taking the KB number. I manually checked it and found the hotfix was sucessful.
$modules = Get-Content .\modules.txt    
$computers = Get-Content .\devices.txt    
$root =  "C$\Installs\Logs"    
    
$computers | %{    
    $comp = $_    
    $modules | %{    
        $instexists = test-path "\\$comp\$root\$_.RTIInst.txt"     
	$verifyexists = test-path "\\$comp\$root\$_.Verify.txt"     
        if($verifyexists){    
            $text = Get-Content "\\$comp\$root\$_.Verify.txt" -ReadCount 0    
            if($text[-3] -eq "Hotfix successfully installed."){$success = "Success"}    
            else{$success = "Fail"}    
        }    
        $mod = $_
        "" | Select-Object -Property @{    
            n="Hostname"; e={$comp}},
            @{n="KBNumber"; e={ = $mod}},
            @{n="Result";e = {if(!$instexists){"NoRTIInst"}elseif(!$verifyexists){"NoVerify"}else{$success}}
        }    
    }    
} | Select-Object hostname, KBNumber, Result |export-csv .\pathreport.csv -notypeinformation

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of soostibi
soostibi
Flag of Hungary image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Great answer. Thanks a lot for the help. It worked nicely.
Once smal change in this please, If the host is not reachable or out of network (can be check with a single ping), then it should say NoConnect in the CSV, please do the needful.
Here you are.
$modules = Get-Content .\modules.txt        
$computers = Get-Content .\devices.txt        
$root =  "C$\Installs\Logs"        
        
$computers | %{        
    $comp = $_ 
    $accessible = Get-Item "\\$comp\c$" -ErrorAction silentlycontinue
    if($accessible){
        $modules | %{        
            $instexists = test-path "\\$comp\$root\$_.RTIInst.txt"         
            $verifyexists = test-path "\\$comp\$root\$_.Verify.txt"         
            if($verifyexists){        
                $text = Get-Content "\\$comp\$root\$_.Verify.txt" -ReadCount 0        
                if($text[-3] -eq "Hotfix successfully installed."){$success = "Success"}        
                else{$success = "Fail"}        
            }        
            $mod = $_    
            "" | Select-Object -Property @{        
                n="Hostname"; e={$comp}},    
                @{n="KBNumber"; e={$mod}},    
                @{n="Result";e = {if(!$instexists){"NoRTIInst"}elseif(!$verifyexists){"NoVerify"}else{$success}}    
            }
    	}
	}
    else {
        "" | Select-Object -Property @{        
            n="Hostname"; e={$comp}},    
            @{n="KBNumber"; e={""}},    
            @{n="Result";e = {"NoConnect"}    
        }       
    }        
} | Select-Object hostname, KBNumber, Result |export-csv .\pathreport.csv -notypeinformation

Open in new window

Thanks a lot, it worked super fine. Thank u very much.