Topic: Reusable Code III
Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.
Back again.
We’ve made two new changes to the below code. One, we replaced powershell_ise, inside of our Get-Process command, with $Service. Two, we added a new, first line to our code. This command will prompt the user to enter a value. Read-Host will then assign that value to the $Service variable. That value will be used in the remainder of the PowerShell code every place $Service is found (there’s only the one). Now, the code is no longer only good for checking for the powershell_ise process; it’ll check for whatever process is entered.
$Service = Read-Host -Prompt 'Enter a Process Name' Get-Process -Name $Service | Select-Object -Property @{N='Process Name';E={$_.Name}}, Description, Company, @{N='Shared Memory';E={"$([Math]::Round($_.WorkingSet / 1MB)) MB"}}, @{N='Private Memory Size'; E={"$([Math]::Round($_.PrivateMemorySize / 1MB)) MB"}}
If you were to open notepad, you could use this code to return its process information. So let’s do that; let’s say we have notepad open and we run our code.
Enter a Process Name: Enter a Process Name: notepad Process Name : notepad Description : Notepad Company : Microsoft Corporation Shared Memory : 9 MB Private Memory Size : 1 MB
Our few lines of code just became useable against any running process on the computer. To be as thorough as possible, we need to consider what happens when we enter a process that isn’t actually running — what’s it going to do? Let’s close notepad and find out.
Enter a Process Name: notepad Get-Process : Cannot find a process with the name "notepad". Verify the process name and call the cmdlet again. At line:3 char:1 + Get-Process -Name $Service | + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (notepad:String) [Get-Process], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
Get-Process doesn’t handle this gracefully, so let’s make a few more changes. We’ll first add a try-catch. The try portion will wrap the Get-Process and Select-Object commands. While it isn’t always necessary, we need to add the ErrorAction parameter name, with the Stop parameter value to Get-Process. This is required in order to prevent this error from being displayed. Forcing a terminating error isn’t always required, so don’t add it to commands when it’s not necessary. You try it without -ErrorAction. If it doesn’t work, you try -ErrorAction SilentlyContinue, and if that doesn’t work, you use -ErrorAction Stop, as we’ve done here.
The catch portion of our try-catch wraps a newly added, Write-Warning command that will gracefully indicate when a process isn’t running, or perhaps, just wasn’t spelled correctly.
$Service = Read-Host -Prompt 'Enter a Process Name' try { Get-Process -Name $Service -ErrorAction Stop | Select-Object -Property @{N='Process Name';E={$_.Name}}, Description, Company, @{N='Shared Memory';E={"$([Math]::Round($_.WorkingSet / 1MB)) MB"}}, @{N='Private Memory Size'; E={"$([Math]::Round($_.PrivateMemorySize / 1MB)) MB"}} } catch { Write-Warning -Message "Cannot locate the $Service process." } Here’s what happens now, when you enter a process that isn’t running, or doesn’t even exist. [powershell] Enter a Process Name: notepad WARNING: Cannot locate the notepad process. Enter a Process Name: asdf WARNING: Cannot locate the asdf process.
That’s it for this Monday. Keep paying attention; it’s about to get good.