SecurityFever icon indicating copy to clipboard operation
SecurityFever copied to clipboard

Impersonation not working in Powershell 7

Open Skaldhor opened this issue 3 years ago • 2 comments

Impersonation working fine in Powershell 5.1.19041.1320

Errors when using Powershell 7.2.1:

Running: Push-ImpersonationContext -Credential "PcName\UserName"

Output (after typing in the password):

New-Object: PowerShell\Modules\SecurityFever\2.8.1\Helpers\Impersonation\Initialize-ImpersonationContext.ps1:64:40
Line |
  64 |  … onContext = New-Object -TypeName 'System.Collections.Generic.Stack[Sy …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Cannot find type [System.Collections.Generic.Stack[System.Security.Principal.WindowsImpersonationContext]]: verify that the assembly containing this type is loaded.

InvalidOperation: PowerShell\Modules\SecurityFever\2.8.1\Functions\Impersonation\Push-ImpersonationContext.ps1:82:5
Line |
  82 |      $newImpersonationContext = [System.Security.Principal.WindowsIden …
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Method invocation failed because [System.Security.Principal.WindowsIdentity] does not contain a method named 'Impersonate'.

InvalidOperation: PowerShell\Modules\SecurityFever\2.8.1\Functions\Impersonation\Push-ImpersonationContext.ps1:83:5
Line |
  83 |      $Script:ImpersonationContext.Push($newImpersonationContext)
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | You cannot call a method on a null-valued expression.

Could you please fix this for PS7?

Thanks and best regards, Skaldhor

Skaldhor avatar Jan 15 '22 15:01 Skaldhor

Same issue with PS 7.2.2

Skaldhor avatar Apr 08 '22 15:04 Skaldhor

Here's what I've learned so far:

  • Powershell 5.1
    • is generically called "Windows Powershell"
    • runs only on Windows, hence the name
    • hooks into ".Net Framework"
  • Powershell 7
    • is aptly called "Powershell", but is also known as "Powershell Core"
    • hooks into ".Net Core", but not ".Net Framework"
    • Powershell 7 code base was originally forked from Windows Powershell but is to support cross platform compatibility
    • Powershell 7 should be called something like generic like"Universal Powershell" to retain the naming convention introduced with "Windows Powershell"
    • Universal Powershell Is a stand alone version of powershell and will co-exist with previously installed versions of "Windows Powershell"
    • Universal Powershell has about 25% of the commandlets available to Windows Powershell
  • .Net Core was specifically designed to not support WindowsImpersonationContext due to security concerns around the function

Recommended solution for your user impersonation. It's not ideal : instead of trying to push impersonation you can refactor your command to use Start-Job which will accept a credential.

Example: In Get-MySqlData I'm calling a private function called Invoke-SQL contained in my automatically loaded module.

The Get-MySqlData function will:

  • Accept all the usual particulars like SQL statement, Credential, and Database Info.
  • Pass parameters into a Start-Job using the credential and run the script block to call Invoke-SQL
  • Wait for the job to complete
  • Return the results
function Get-MySqlData {
      param ( 
         [string]$SqlStatement
         , [PsCredential]$Credential = $( Get-Credential )
         ,  [string]$Database = "DatabaseInstanceName"
         ,  [string]$Server = "DatabaseServerName"
         ) # end param
      $ScriptBlock = {
          Param( [hashtable]$Options )
          write-host "welcome '$($Env:username)'"
          write-host "`$Options = $($Options | ConvertTo-Json) # end json"
          Invoke-SQL @Options
          } # end scriptblock
      $Options = @{
          SqlStatement = $SqlStatement
          Database = $Database
          Server = $Server
          } # end hash
      $Job = Start-Job -ScriptBlock $ScriptBlock -Credential $Credential -ArgumentList $Options
      return $Job | Wait-Job | Receive-Job
      } # end function Get-MySqlData

RoYoMi avatar Jan 08 '23 00:01 RoYoMi