Tuesday, April 21, 2015

Powershell - Com+ Application Recycle

Needed a script to recycle a com+ application nightly and this is what i came up with. This script will write each recycle it does to the event log under application. Run locally or via a scheduled task.
#Recycle COM+ Application and write to the event log the status
# 1.0 Release
# Run script locally
# Write to the event log


########################################
#Configurable
########################################
#Com+ ApplicationName
$ComPlusLikeAppName = "Put the name of Com+ Application here a like statement is used to eval so you can get away with putting part of it"
#EventLog to write to.
$eventlog = "Application"
#Source for eventlog.
$source = "RecycleComObject"
#Successful Event ID
$SEventID = 0
#Error Event ID
$EEventID = 666
#Process that COM+ runs under
$process = "dllhost.exe".
########################################

#Clear
$CurrentMemory = $null
$PRocessID = $null
$Commandline = $null
$GUID = $null
$AppID = $null
$Message = $null
$ConvertedMemory = $null
$CheckProcessID= $null 



#Clear errors
$ErrorMsg = $null
$error.clear()

#Create event source for writing to the eventlog if does not already exist.
if(![System.Diagnostics.EventLog]::SourceExists($source)) {
                [System.Diagnostics.EventLog]::CreateEventSource($source , $eventlog);
}

$RecycleReason = 1
$comAdmin = New-Object -com COMAdmin.COMAdminCatalog
$applist = $comAdmin.GetCollection("Applications") 
$applist.Populate()
$AppID = $applist | where {$_.Name -like "*$ComPlusLikeAppName*"} | select -expand key


#Find Process ID
$Commandline = Get-WmiObject Win32_Process -Filter "name = '$process'" | select ProcessID,CommandLine
$ProcessID = $Commandline | where {$_.Commandline -like "*$AppID*"} | Select -expand ProcessID


#If two process with the same GUI assume dllhost is in middle of recycle
if ($ProcessID.count -gt 1){
$Message = "Please wait up to 15 minutes(default) as there are two PID with the same $AppID" 

Write-EventLog -LogName $eventlog -Source $source -EventId $SEventID -EntryType Information –Message $Message

exit

}


#
#Get GUID from Process ID
$GUID = $comAdmin.GetApplicationInstanceIDFromProcessID($ProcessID)

#GetCurrentMemory 
$CurrentMemory = get-process -id $ProcessID | select -ExpandProperty "PrivateMemorySize"

#Event Messages


write-host "Process ID:$ProcessID"
Write-host "ApplicationID:$AppID"
write-host "GUID:$GUID"
$ConvertedMemory = [math]::truncate($CurrentMemory / 1MB)
Write-Host "CurrentMemory:$ConvertedMemory"




try {
$comAdmin.RecycleApplicationInstances($GUID,$RecycleReason)
}
catch {
#If error is caught 
  $ErrorMsg = [system.exception]"caught a system exception `n $error"
}
Finally
 {
    start-sleep -seconds 5
#Check if there is an increase in the amount of PID
$Commandline = Get-WmiObject Win32_Process -Filter "name = '$process'" | select ProcessID,CommandLine
$CheckProcessID = $Commandline | where {$_.Commandline -like "*$AppID*"} | Select -expand ProcessID


$NewProcessID = $CheckProcessID | where {$_ -notlike "*$ProcessID*"} 
write-host "NewProcessID:$NewProcessID"
$Message = " Process ID:$ProcessID `n ApplicationID:$AppID `n GUID:$GUID `n MemoryBeforeRecycle:$ConvertedMemory MB `n New Process ID:$NewProcessID"


    if($ErrorMsg -ne $null){
         $Message += $ErrorMsg
     Write-EventLog -LogName $eventlog -Source $source -EventId $EEventID -EntryType error –Message $Message
        exit 
}

if ($ProcessID -eq $null -or $AppID -eq $null -or $GUID -eq $Null -or $ConvertedMemory -eq $null -or $NewProcessID -eq $null) {
Write-EventLog -LogName $eventlog -Source $source -EventId $EEventID -EntryType error –Message "$Message `n Value Missing"
        exit 
}

else {
Write-EventLog -LogName $eventlog -Source $source -EventId $SEventID -EntryType Information –Message $Message
}


}

3 comments:

  1. Thank you for this post. This helped me a lot!

    ReplyDelete
    Replies
    1. Thanks this was sort of a hack job. Was hard to find documentation on how to do this.

      Delete
  2. Thank you very much for this script ! :)

    ReplyDelete