PowerShell | Parsing log file for certain line

Hallo all,

I'm trying to monitor the process of uninstalling a SCCM client from a computer. Normally you should give the command "C:\Windows\ccmsetup\ccmsetup.exe /uninstall" and wait for it.

However the uninstall process keeps track of its progress in a logfile which can be found here: "C:\Windows\ccmsetup\Logs\ccmsetup.log".

When the uninstall is completed the last line of the logfile should start with: "<![LOG[CcmSetup is exiting with return code 0]LOG]". Here after there is more information displayed however that is not needed the determine the uninstall has completed successfully.

I seem unable to catch the last line and stop the job and go on with the other steps of uninstalling. Anyone any ideas? This is my code so far:
$SCCMUninstall = "C:\Windows\ccmsetup\ccmsetup.exe /uninstall"
$CCMLog = "C:\Windows\ccmsetup\Logs\ccmsetup.log"

Start-Job $SCCMUninstall

While (! (Test-Path $CCMLog)) {Sleep -Seconds 10}

Write-Host ("Monitoring " + $CCMLog)

Get-Content -Path $CCMLog -Tail 1 -Wait | Where {$_ -like "*<![LOG[CcmSetup is exiting with return code 0]LOG]*"}

Write-Host ("SCCM Client succesfully uninstalled!")

Open in new window

GyroTwisterSenior Windows SpecialistAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jose Gabriel Ortega CastroCEO Faru Bonon IT - EE Solution ExpertCommented:
In the -like try this one:

$_ -match "\<\!\[LOG\[CcmSetup is exiting with return code 0\]LOG\]"

So the whole line would be:
Get-Content -Path $CCMLog -Tail 1 -Wait | Where {$_ -match "\<\!\[LOG\[CcmSetup is exiting with return code 0\]LOG\]"}

Also I redo some lines:

[CmdletBinding()]
param(
    [Parameter(Position=0,Mandatory=$false)]$CCMLog = "C:\Windows\ccmsetup\Logs\ccmsetup.log",
    [Parameter(Position=1,Mandatory=$false)]$SCCMUninstall = "C:\Windows\ccmsetup\ccmsetup.exe /uninstall"
)

    $job =Start-Job $SCCMUninstall
    While (! (Test-Path $CCMLog)) {Sleep -Seconds 10}
    Write-Host ("Monitoring $CCMLog")

    $job | Wait-Job
    #Try it for a file that contains it and then remove the #from the below lines. "#for( and #}"
    do{
        $answer=Get-Content -Path $CCMLog -Tail 1 | Where {$_ -match "\<\!\[LOG\[CcmSetup is exiting with return code 0\]LOG\]"}
        if($answer){
            $isitdone=$true
            break;
        }
    }
    while(!($isitdone))
    Write-Host ("SCCM Client succesfully uninstalled!")

Open in new window

Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Get-Content with the -wait parameter is dynamic. So you need to break it for the script to move on. So even if it matches it will just sit there still monitoring the file if you don't break it.

Try this:

$SCCMUninstall = "C:\Windows\ccmsetup\ccmsetup.exe /uninstall"
$CCMLog = "C:\Windows\ccmsetup\Logs\ccmsetup.log"

Start-Job $SCCMUninstall

While (! (Test-Path $CCMLog)) {Sleep -Seconds 10}

Write-Host ("Monitoring " + $CCMLog)

Get-Content -Path $CCMLog -Tail 1 -Wait | Where {$_ -like "*<![LOG[CcmSetup is exiting with return code 0]LOG]*"} | %{break}

Write-Host ("SCCM Client succesfully uninstalled!")

Open in new window

GyroTwisterSenior Windows SpecialistAuthor Commented:
Hello all,

Thanks for the first pointers. It is still not working as I expect but with the provided solutions from you, I am testing a better script. Once it works I'll let you know.
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Let us know if you have any questions.
GyroTwisterSenior Windows SpecialistAuthor Commented:
Well after a few days of crunching code I came up with the following script to uninstall and re-install the SCCM Client:

<# Declaring Variables #>
$CCMDir = "C:\Windows\CCM"
$CCMLog = "C:\Windows\ccmsetup\Logs\ccmsetup.log"
$CCMRegKey = "HKLM:\Software\Microsoft\CCMSetup"
$CCMSetup = "C:\Windows\ccmsetup\ccmsetup.exe"
$CCMSetupArg = " /uninstall"
$CCMSetupDir = "C:\Windows\ccmsetup"

$NewSetup = "\\<MgmtPoint>\SMS_<SMSSiteCode>\Client\ccmsetup.exe"
$NewSetupArg = " /mp:<MgmtPoint> /logon SMSSITECODE=<SMSSiteCode> FSP=<FallBackPoint>"

$SMSCFG = "C:\Windows\SMSCFG.ini"
$SMSMIF = "C:\Windows\SMS*.mif"
$SMSRegKey = "HKLM:\Software\Microsoft\SMS"

Clear-Host

<# Delete an existing log file #>
If (Test-Path $CCMLog) {Remove-Item $CCMLog; Write-Host "Deleting existing Logfile" -ForegroundColor Green}

<# Uninstalling SCCM Client #>
Start-Process $CCMSetup $CCMSetupArg

Do {
    $Answer = Get-Process ccmsetup -ErrorAction SilentlyContinue
    If (! ($Answer)) {
        Write-Host "CCMSetup not yet started, sleeping......" -ForegroundColor Green
        Start-Sleep -Seconds 2
        }
    }
    Until ($Answer)

<# Clear Variable for Re-Use #>
Clear-Variable Answer

<# Check for existence of log-file #>
If (! (Test-Path $CCMLog)) {Start-Sleep -Seconds 2}
Write-Host "Monitoring LogFile" -ForegroundColor Green

<# Monitoring the log file for successfull uninstall of client #>
Do {
    $Answer = Get-Content -Path $CCMLog -Tail 1 | Where {$_ -match "\<\!\[LOG\[CcmSetup is exiting with return code 0\]LOG\]"}
    If ($Answer) {
        $IsItDone = $True
        break;
        }
    }
    Until ($IsItDone)

<# Clear Variable for Re-Use #>
Clear-Variable Answer
Clear-Variable IsItDone
    
<# Check if process has stopped #>
Do {
    $Answer = Get-Process ccmsetup -ErrorAction SilentlyContinue
    If ($Answer) {
        Write-Host "CCMSetup still running, sleeping......" -ForegroundColor Green
        Start-Sleep -Seconds 2
        }
    }
    Until (! ($Answer))

<# Clear Variable for Re-Use #>
Clear-Variable Answer

<# Deletion of obsolete registry key #>
If (Test-Path $CCMRegKey) {Remove-Item -Path $CCMRegKey -Recurse -Force -ErrorAction SilentlyContinue; Write-Host "Deleting CCM Registry" -ForegroundColor Green}
If (Test-Path $SMSRegKey) {Remove-Item -Path $SMSRegKey -Recurse -Force -ErrorAction SilentlyContinue; Write-Host "Deleting SMS Registry" -ForegroundColor Green}

<# Deletion of obsolete directories #>
If (Test-Path $CCMDir) {Remove-Item -Path $CCMDir -Recurse -Force -ErrorAction SilentlyContinue; Write-Host "Deleting directory CCM" -ForegroundColor Green}
If (Test-Path $CCMSetupDir) {Remove-Item -Path $CCMSetupDir -Recurse -Force -ErrorAction SilentlyContinue; Write-Host "Deleting directory CCMSetup" -ForegroundColor Green}

<# Deletion of obsolete files #>
if (Test-Path $SMSCFG) {Remove-Item $SMSCFG; Write-Host "Deleting SMS Config" -ForegroundColor Green}
if (Test-Path $SMSMIF) {Remove-Item $SMSMIF; Write-Host "Deleting SMS*.mif" -ForegroundColor Green}

Write-Host "SCCM Client succesfully uninstalled!" -ForegroundColor Yellow

Write-Host "Sleeping 5 seconds before reinstall of SCCM Client" -ForegroundColor Cyan
Start-Sleep -Seconds 5

<# Installing SCCM Client #>
Start-Process $NewSetup $NewSetupArg -Verb RunAs

Do {
    $Answer = Get-Process ccmsetup -ErrorAction SilentlyContinue
    If (! ($Answer)) {
        Write-Host "CCMSetup not yet started, sleeping......" -ForegroundColor Cyan
        Start-Sleep -Seconds 2
        }
    }
    Until ($Answer)

<# Clear Variable for Re-Use #>
Clear-Variable Answer

<# Check for existence of log-file #>
If (! (Test-Path $CCMLog)) {Start-Sleep -Seconds 2}
Write-Host "Monitoring LogFile" -ForegroundColor Cyan

<# Monitoring the log file for successfull install of client #>
Do {
    $Answer = Get-Content -Path $CCMLog -Tail 1 | Where {$_ -match "\<\!\[LOG\[CcmSetup is exiting with return code 0\]LOG\]"}
    If ($Answer) {
        $IsItDone = $True
        break;
        }
    }
    Until ($IsItDone)

<# Clear Variable for Re-Use #>
Clear-Variable Answer
Clear-Variable IsItDone
    
<# Check if process has stopped #>
Do {
    $Answer = Get-Process ccmsetup -ErrorAction SilentlyContinue
    If ($Answer) {
        Write-Host "CCMSetup still running, sleeping......" -ForegroundColor Cyan
        Start-Sleep -Seconds 2
        }
    }
    Until (! ($Answer))

Write-Host "SCCM Client successfully installed!" -ForegroundColor Cyan

Open in new window


This is working quite good. However I could use some pointers how to improve the script. For example I'm looking for an indicator while the program is (in)installing. At this time I only see the line "Monitoring LogFile". Is there a possibility to show something of progress while monitoring the log-file?

Any comment is welcome!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
To get the status, you would need to be getting feedback from the uninstall process and then know how to interpret that feedback to give relevant status info. I'm not sure how to do that.

You could show the timestamp of when the uninstall started and that might be a good enough gauge to know how much time is left... ?
GyroTwisterSenior Windows SpecialistAuthor Commented:
-
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.