Home > Blockchain >  How to restart a powershell instance?
How to restart a powershell instance?

Time:11-10

What is the most efficient way to restart the PowerShell instance from within the PowerShell terminal?

Currently I do the following:

pwsh

This seems to start a new instance, but I am not sure whether this is restarting the processes or merely starting a new process.

CodePudding user response:

Running pwsh merely starts a new session in a child process of the current one, which lives on, and is returned to when you exit from the new one.
What you're probably looking for is to replace the current session with a new one.


  • On Unix-like platforms, in PowerShell (Core) v7.3 , you can use exec (the built-in alias of the Switch-Process cmdlet) to replace the current process with a different one:

    # PS v7.3 , on Unix
    exec pwsh
    
    • In v7.2-, there's no simple solution, though you could consider use of (my) ttab utility.
  • On Windows, there is no direct equivalent:

    • In regular console windows (conhost.exe), as Mathias R. Jessen points out, you can can achieve the same effect as follows:

      & (Get-Process -Id $PID).Path -NoExit -c "Stop-Process -Id $PID"
      
    • Unfortunately, this doesn't work in Windows Terminal, but you can use its CLI, wt.exe:

      wt.exe -w 0 -p $env:WT_PROFILE_ID
      

Note:

  • The first two methods inherit the original session's environment variables and the current location (directory), but nothing else.

  • The Windows Terminal method does not.


For convenience, you can wrap these calls in a custom, cross-platform and cross-edition function, say New-Session, which you can place in your $PROFILE file; you may also define a short alias for it, say ns:

Set-Alias ns New-Session # define an alias

function New-Session {
  $envInheritanceNote = 'Note: Environment was INHERITED from previous session.'
  $envNonInheritanceNote = 'Note: Environment was NOT INHERITED from previous session.'
  if ($env:OS -eq 'Windows_NT') {
    if ($env:WT_PROFILE_ID) { # Windows Terminal
      # Windows Terminal: open a new tab in the current window using the same profile, then exit the current tab.
      # NOTE:
      #  * Does NOT inherit the calling shell's environment - only the environment of the master WT executable ('WindowsTerminal'),
      #    of which there is 1 per window. 
      #    (The tabs of a new window getting launched via wt.exe from a shell in a *regular console window*, for instance, DO inherit the caller's environment.)
      #  * The `Start-Sleep` call is to prevent the current tab
      #    from closing instantly, which, if it happens to be the only
      #    open tab, would close the Windows Terminal window altogether,
      #    *before* the newly launched tab opens.
      wt.exe -w 0 -p $env:WT_PROFILE_ID (Get-Process -Id $PID).Path -NoExit -Command "Write-Verbose -vb '$envNonInheritanceNote'"; Start-Sleep 1; exit
    }
    else { # regular console window (conhost.exe)
      & (Get-Process -Id $PID).Path -NoExit -c "Stop-Process -Id $PID; Write-Verbose -vb '$envInheritanceNote'"
    }
  }
  else {
    # Unix
    if ($PSVersionTable.PSVersion.Major -gt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -ge 3)) {
      # PSv7.3 : use `exec` (built-in alias for `Switch-Process`) to replace the current shell process inside the current window.
      exec pwsh -noexit -c "Write-Verbose -vb '$envInheritanceNote'"
    }
    else { # PSv7.2-: not supported.
      throw "Not supported in PowerShell versions up to v7.2.x"
    }
  }
  exit
}
  • Related