{"id":71822,"date":"2015-07-31T00:01:00","date_gmt":"2015-07-31T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/07\/31\/whats-my-pid\/"},"modified":"2019-02-18T09:46:47","modified_gmt":"2019-02-18T16:46:47","slug":"whats-my-pid","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/whats-my-pid\/","title":{"rendered":"What&#8217;s My PID?"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Ed Wilson, Microsoft Scripting Guy, creates a function to capture the process ID of a Windows PowerShell host.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. One of the things I like to know is the process ID (PID) of specific processes. Often this is trivial. I can use <b>the Get-Process<\/b> cmdlet and, for example, look to see what the process ID of Notepad.exe is. But what if I have four or five instances of Notepad running? Then it becomes somewhat an exercise in trial and error.<\/p>\n<p>This is also true for Windows PowerShell. For example, the Windows PowerShell console process name is PowerShell. No problem. Except that I often have multiple instances of Windows PowerShell running, and quite often they are all doing different things.<\/p>\n<p>So, whereas the <b>$host<\/b> automatic variable represents the Windows PowerShell console host, and it has an instance ID, I cannot easily reference that instance ID to a process ID. So, I had this idea about adding a member to the <b>$host<\/b> variable. Not too big of a deal. In fact, it is something that I could do since Windows PowerShell&nbsp;1.0 by using the <b>Add-Member<\/b> cmdlet.<\/p>\n<p><span style=\"font-size:12px\">I need to know which instance of Windows PowerShell I am talking about, and I need a way to differentiate which is which. One way I can do that is by using the <\/span><b style=\"font-size:12px\">StartTime<\/b><span style=\"font-size:12px\"> property from the process object that I obtain via the <\/span><b style=\"font-size:12px\">Get-Process<\/b><span style=\"font-size:12px\"> cmdlet.<\/span><\/p>\n<p>Now, to what do I compare it? Well obviously, with the date from <b>Get-Date<\/b>. So, I decided to capture the date as soon as I can and compare it with the <b>StartTime<\/b> property from <b>Get-Process<\/b>. The result? For me, it works nearly all the time, and that is good enough for something like this.<\/p>\n<p>At first, it was easy, I simply captured the process ID and add it to <b>$host<\/b>. But that quickly did not work because if I have multiple instances of Windows PowerShell running (more likely than not in my case), I have an array of process IDs&mdash;and that doesn&rsquo;t do any good.<\/p>\n<p>But in fact, when I have multiple instances of Windows PowerShell running, that is THE time when it is most important to know which instance is which. So that added to the complexity of my Windows PowerShell function.<\/p>\n<p>The first thing I do is use the <b>Foreach<\/b> statement and walk through a collection of Windows PowerShell processes. If the start time matches the current date time, I use the <b>Add-Member<\/b> cmdlet to add the PID to a property I created called <b>PID<\/b>. Otherwise, I don&rsquo;t do anything.<\/p>\n<p>Here is the function:<\/p>\n<p style=\"margin-left:30px\">Function Get-HostPid<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Foreach($p in (Get-Process PowerShell))<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; if ($p.StartTime.Touniversaltime() -match<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Get-Date).ToUniversalTime())<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; { $host | Add-Member -NotePropertyName PID -NotePropertyValue ($p.ID)}}}<\/p>\n<p>The first thing I do when processing commands in my Windows PowerShell profile is to call the <b>Get-HostPID<\/b> function. This gives me the best chance for success. The command is simple:<\/p>\n<p style=\"margin-left:30px\">Get-HostPID<\/p>\n<p>Here is the output from <b>the $host<\/b> variable now:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/Hsg-7-31-15-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/Hsg-7-31-15-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The complete Windows PowerShell profile is shown here:<\/p>\n<p style=\"margin-left:30px\">#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p style=\"margin-left:30px\">#<\/p>\n<p style=\"margin-left:30px\"># PowerShell console profile<\/p>\n<p style=\"margin-left:30px\"># ed wilson, msft<\/p>\n<p style=\"margin-left:30px\">#<\/p>\n<p style=\"margin-left:30px\"># NOTES: contains five types of things: aliases, functions, psdrives,<\/p>\n<p style=\"margin-left:30px\"># variables and commands.<\/p>\n<p style=\"margin-left:30px\"># version 1.2<\/p>\n<p style=\"margin-left:30px\"># 7\/27\/2015<\/p>\n<p style=\"margin-left:30px\"># HSG 7-28-2015<\/p>\n<p style=\"margin-left:30px\">#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p style=\"margin-left:30px\">#Aliases<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name ep -Value edit-profile | out-null<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name tch -Value Test-ConsoleHost | out-null<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name gfl -Value Get-ForwardLink | out-null<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name gwp -Value Get-WebPage | out-null<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name rifc -Value Replace-InvalidFileCharacters | out-null<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name gev -Value Get-EnumValues | out-null<\/p>\n<p style=\"margin-left:30px\">Set-Alias -Name sudo -Value Start-ElevatedPowerShell | out-null<\/p>\n<p style=\"margin-left:30px\">#Variables<\/p>\n<p style=\"margin-left:30px\">New-Variable -Name doc -Value &quot;$home\\documents&quot; `<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; -Description &quot;My documents library. Profile created&quot; `<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; -Option ReadOnly -Scope &quot;Global&quot;<\/p>\n<p style=\"margin-left:30px\">if(!(Test-Path variable:backupHome))<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;new-variable -name backupHome -value &quot;$doc\\WindowsPowerShell\\profileBackup&quot; `<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; -Description &quot;Folder for profile backups. Profile created&quot; `<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; -Option ReadOnly -Scope &quot;Global&quot;<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">#PS_Drives<\/p>\n<p style=\"margin-left:30px\">New-PSDrive -Name Mod -Root ($env:PSModulePath -split &#039;;&#039;)[0] `<\/p>\n<p style=\"margin-left:30px\">&nbsp;-PSProvider FileSystem | out-null<\/p>\n<p style=\"margin-left:30px\">#Functions<\/p>\n<p style=\"margin-left:30px\">Function Edit-Profile<\/p>\n<p style=\"margin-left:30px\">{ ISE $profile }<\/p>\n<p style=\"margin-left:30px\">Function Test-ConsoleHost<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;if(($host.Name -match &#039;consolehost&#039;)) {$true}<\/p>\n<p style=\"margin-left:30px\">&nbsp;Else {$false}&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function Replace-InvalidFileCharacters<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Param ($stringIn,<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $replacementChar)<\/p>\n<p style=\"margin-left:30px\">&nbsp;# Replace-InvalidFileCharacters &quot;my?string&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;# Replace-InvalidFileCharacters (get-date).tostring()<\/p>\n<p style=\"margin-left:30px\">&nbsp;$stringIN -replace &quot;[$( [System.IO.Path]::GetInvalidFileNameChars() )]&quot;, $replacementChar<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function Get-TranscriptName<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;$date = Get-Date -format s<\/p>\n<p style=\"margin-left:30px\">&nbsp; &quot;{0}.{1}.{2}.txt&quot; -f &quot;PowerShell_Transcript&quot;, $env:COMPUTERNAME,<\/p>\n<p style=\"margin-left:30px\">&nbsp; (rifc -stringIn $date.ToString() -replacementChar &quot;-&quot;) }<\/p>\n<p style=\"margin-left:30px\">Function Get-WebPage<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Param($url)<\/p>\n<p style=\"margin-left:30px\">&nbsp;# Get-WebPage -url (Get-CmdletFwLink get-process)<\/p>\n<p style=\"margin-left:30px\">&nbsp;(New-Object -ComObject shell.application).open($url)<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function Get-ForwardLink<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Param($cmdletName)<\/p>\n<p style=\"margin-left:30px\">&nbsp;# Get-WebPage -url (Get-CmdletFwLink get-process)<\/p>\n<p style=\"margin-left:30px\">&nbsp;(Get-Command $cmdletName).helpuri<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function BackUp-Profile<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Param([string]$destination = $backupHome)<\/p>\n<p style=\"margin-left:30px\">&nbsp; if(!(test-path $destination))<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; {New-Item -Path $destination -ItemType directory -force | out-null}<\/p>\n<p style=\"margin-left:30px\">&nbsp; $date = Get-Date -Format s<\/p>\n<p style=\"margin-left:30px\">&nbsp; $backupName = &quot;{0}.{1}.{2}.{3}&quot; -f $env:COMPUTERNAME, $env:USERNAME,<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; (rifc -stringIn $date.ToString() -replacementChar &quot;-&quot;),<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; (Split-Path -Path $PROFILE -Leaf)<\/p>\n<p style=\"margin-left:30px\">&nbsp;copy-item -path $profile -destination &quot;$destination\\$backupName&quot; -force<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function get-enumValues<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;# get-enumValues -enum &quot;System.Diagnostics.Eventing.Reader.StandardEventLevel&quot;<\/p>\n<p style=\"margin-left:30px\">Param([string]$enum)<\/p>\n<p style=\"margin-left:30px\">$enumValues = @{}<\/p>\n<p style=\"margin-left:30px\">[enum]::getvalues([type]$enum) |<\/p>\n<p style=\"margin-left:30px\">ForEach-Object {<\/p>\n<p style=\"margin-left:30px\">$enumValues.add($_, $_.value__)<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">$enumValues<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function Test-IsAdmin<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;&lt;#<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; .Synopsis<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tests if the user is an administrator<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; .Description<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Returns true if a user is an administrator, false if the user is not an administrator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; .Example<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Test-IsAdmin<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; #&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;$identity = [Security.Principal.WindowsIdentity]::GetCurrent()<\/p>\n<p style=\"margin-left:30px\">&nbsp;$principal = New-Object Security.Principal.WindowsPrincipal $identity<\/p>\n<p style=\"margin-left:30px\">&nbsp;$principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function Start-ElevatedPowerShell<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Start-Process PowerShell -Verb Runas<\/p>\n<p style=\"margin-left:30px\">&nbsp;}<\/p>\n<p style=\"margin-left:30px\">Function Get-HostPid<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Foreach($p in (Get-Process PowerShell))<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; if ($p.StartTime.Touniversaltime() -match<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Get-Date).ToUniversalTime())<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; { $host | Add-Member -NotePropertyName PID -NotePropertyValue ($p.ID)}}}<\/p>\n<p style=\"margin-left:30px\">#Commands<\/p>\n<p style=\"margin-left:30px\">Get-HostPid<\/p>\n<p style=\"margin-left:30px\">Set-Location c:\\<\/p>\n<p style=\"margin-left:30px\">If(tch) {Start-Transcript -Path (Join-Path -Path `<\/p>\n<p style=\"margin-left:30px\">&nbsp;$doc -ChildPath $(Get-TranscriptName))}<\/p>\n<p style=\"margin-left:30px\">BackUp-Profile<\/p>\n<p style=\"margin-left:30px\">if(Test-IsAdmin)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; { $host.UI.RawUI.WindowTitle = &quot;Elevated PowerShell&quot; }<\/p>\n<p style=\"margin-left:30px\">else { $host.UI.RawUI.WindowTitle = &quot;Mr $($env:USERNAME) Non-elevated Posh&quot; }<\/p>\n<p>That is how you can use Windows PowerShell to find a PID. Join me tomorrow when I will talk about more cool stuff.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, creates a function to capture the process ID of a Windows PowerShell host. Microsoft Scripting Guy, Ed Wilson, is here. One of the things I like to know is the process ID (PID) of specific processes. Often this is trivial. I can use the Get-Process cmdlet and, for example, [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,144,3,4,45],"class_list":["post-71822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-profiles","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, creates a function to capture the process ID of a Windows PowerShell host. Microsoft Scripting Guy, Ed Wilson, is here. One of the things I like to know is the process ID (PID) of specific processes. Often this is trivial. I can use the Get-Process cmdlet and, for example, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=71822"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71822\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=71822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=71822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=71822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}