{"id":71862,"date":"2015-07-29T00:01:00","date_gmt":"2015-07-29T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/07\/29\/use-function-to-determine-elevation-of-powershell-console\/"},"modified":"2019-02-18T09:46:48","modified_gmt":"2019-02-18T16:46:48","slug":"use-function-to-determine-elevation-of-powershell-console","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-function-to-determine-elevation-of-powershell-console\/","title":{"rendered":"Use Function to Determine Elevation of PowerShell Console"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Ed Wilson, Microsoft Scripting Guy, talks about using a function to determine if a Windows PowerShell console is elevated.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. I had a friend tell me that nearly half of all the cmdlets, functions, and whatever&rsquo;s in Windows PowerShell&nbsp;4.0 on Windows Server&nbsp;2012&nbsp;R2 required elevation to Admin rights. I can neither confirm nor deny this assertion, and I have not seen any official documentation about this. But I can tell you, that there are quite a few of these things that do require elevation. For example, the Hyper-V functions (even in Windows&nbsp;8.1) require elevation. Even worse, when not elevated, you do not even get a report with an &quot;access denied&quot; type of error.<\/p>\n<p>My friend&#039;s solution was simply to run Windows PowerShell elevated all the time, but my security background will not permit me to do that. I want to only use elevation when required. When I am done, I close out the elevated Windows PowerShell console, and go back to using my non-elevated Windows PowerShell console.<\/p>\n<p>Although I normally run the Windows PowerShell console and the Windows PowerShell ISE with non-elevated rights, there are times when I need to know if I have elevated things. This is where my <b>Test-IsAdmin<\/b> function comes into play. I include this function in my Windows PowerShell Best Practices book, but it comes from a discussion on the internal Windows PowerShell alias at Microsoft from before Windows PowerShell was even called Windows PowerShell.<\/p>\n<p>We were looking at various ways to determine if the current user has Admin rights, and this is the technique we pretty well settled on. I have written various versions of this, but I like this current version pretty well. Here is the function:<\/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>The function returns a <b>$true<\/b> Boolean value if the user is in the role of administrator or <b>$false<\/b> if the user is not in the role of administrator. Luckily, when I elevate my Windows PowerShell console, I am in the role of administrator. When not elevated, I am not in that role. Cool how that works out.<\/p>\n<p>So in my Windows PowerShell profile, I call the function, and then evaluate the results. I then change my Windows PowerShell title based on what the function call reports:<\/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>I place this code directly after I back up the Windows PowerShell profile. The resulting Windows PowerShell console is shown here when it is not elevated:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/Hsg-7-29-15-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/Hsg-7-29-15-01.png\" alt=\"Image of console\" title=\"Image of console\" \/><\/a><\/p>\n<p>This image shows the console when I right-click the Windows PowerShell icon and select <b>Run as Administrator<\/b>:<\/p>\n<p><span style=\"font-size:12px\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/Hsg-7-29-15-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/Hsg-7-29-15-02.png\" alt=\"Image of console\" title=\"Image of console\" \/><\/a><br \/><\/span><\/p>\n<p><span style=\"font-size:12px\">Here is my complete Windows PowerShell profile:<\/span><\/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\">#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\">#Commands<\/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 all there is to using a function to determine if the Windows PowerShell console is elevated. 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, talks about using a function to determine if a Windows PowerShell console is elevated. Microsoft Scripting Guy, Ed Wilson, is here. I had a friend tell me that nearly half of all the cmdlets, functions, and whatever&rsquo;s in Windows PowerShell&nbsp;4.0 on Windows Server&nbsp;2012&nbsp;R2 required elevation to Admin rights. I [&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":[69,51,144,3,4,63,45],"class_list":["post-71862","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-functions","tag-getting-started","tag-profiles","tag-scripting-guy","tag-scripting-techniques","tag-security","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, talks about using a function to determine if a Windows PowerShell console is elevated. Microsoft Scripting Guy, Ed Wilson, is here. I had a friend tell me that nearly half of all the cmdlets, functions, and whatever&rsquo;s in Windows PowerShell&nbsp;4.0 on Windows Server&nbsp;2012&nbsp;R2 required elevation to Admin rights. I [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71862","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=71862"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71862\/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=71862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=71862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=71862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}