1

I created a script that's relaunching itself with elevated privileges when it's run without these:

Here's the code:

using namespace System.Security.Principal
using namespace System.Management.Automation

[CmdletBinding()]
param ([Int32]$B)


<#
.SYNOPSIS
    Runs the current script with elevated privileges.

.DESCRIPTION
    If the current script is not running with elevated privileges,
    a new PowerShell session is launched with elevated privileges
    and the current script is run therein.

.PARAMETER InvInfo
    InvocationInfo object to observe.

.PARAMETER WorkDir
    Working directory the original script has been launched from. (Used for resolving the original command line arguments.)
#>
function RunElevated
{
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $true, Position = 0)][InvocationInfo]$InvInfo,
    [Parameter(Mandatory = $true, Position = 1)][string]$WorkDir
  )

  if (([WindowsPrincipal][WindowsIdentity]::GetCurrent()).IsInRole([WindowsBuiltInRole]::Administrator) -eq $false)
  {
    $ErrorActionPreference = 'Ignore'
    Start-Process 'PowerShell' -Verb 'RunAs' -ArgumentList "-Command Set-Location '$WorkDir'; $($InvInfo.Line)"
    Exit
  }
}



RunElevated -InvInfo $MyInvocation -WorkDir (Get-Location).Path

# test code
$ErrorActionPreference = 'Stop'
$B
Get-Location    # doesn't output anything
Get-ChildItem   # doesn't output anything
Start-Sleep -Seconds 5

Testing my script I made a strange observation: Get-Location and Get-ChildItem don't output anything. (See comments: # doesn't output anything)

However, if I replace Get-Location with "$(Get-Location)", everything is output fine:

# test code
$ErrorActionPreference = 'Stop'
$B
"$(Get-Location)"  # outputs flawlessly
Get-ChildItem      # outputs flawlessly
Start-Sleep -Seconds 5

What did I do wrong? Why aren't the above CmdLets outputting to the console?

AxD
  • 2,714
  • 3
  • 31
  • 53
  • 1
    In short: This is a _display_ problem: Your output results in implicit `Format-Table` formatting, which incurs a 300-msec. delay before output is rendered (to determine suitable column widths). `Start-Sleep` suspends this delay, because it suspends the foreground thread. Therefore, output won't show until after `Start-Sleep` ends (and 300 msecs. have elapsed, not counting sleep periods). The - suboptimal - workaround is to force _synchronous_ display output. See the linked duplicate for details. – mklement0 May 19 '22 at 17:32
  • 1
    _Strings_ are always displayed _synchronously_, which is why `"$(Get-Location)"` bypassed the problem. – mklement0 May 19 '22 at 17:33
  • To me, the current behavior doesn't make sense. It makes to sense to join multiple discrete statements into a single output. I raised an issue with the PowerShell team here: https://github.com/PowerShell/PowerShell/issues/17392 – AxD Jun 04 '22 at 14:58

0 Answers0