DavidBla
DavidBla

Reputation: 13

Powershell run privileged commands from non privileged user by passing credentials

i've some trouble with executing command that need more privileges than the calling user has.

I wrote a "admin repository" of powershell scripts & snippets for management reasons. I create a auto importer script and also an auto update if i release a new tag. Works like a charm!

But than we decieded to split some privileges to other users to fulfill some JEA requirements.

Now our unprivileged "working" users are importing the repository and are not allowed to run every command. (eg. querying DHCP sever)

I thought it would be no issue - thought about the Get-Credential simply running the priv features with the priv user.... but i was wrong... it's not simple as i thought.

First issue was that the command does not accept a -credential param. i ended up with something like this:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "powershell"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Domain = $cred.UserName.Split('\')[0] 
$pinfo.Password = $cred.Password
$pinfo.UserName = $cred.UserName.Split('\')[1]
$pinfo.CreateNoWindow = $true
$pinfo.Arguments = "Get-DhcpServerv4Scope -computername $server"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
$p.WaitForExit()

it took me some time to get the output of this session to a variable... fist i wrote output to a tmp file and red it with the other session, but it feels like I do it terrible wrong.

Now I've to parse the output, create a template and build the object again - i've to change half of the script and it become slow and I dont like the way....

I can't escape the feeling that there is a better way - so im asking you :)

Best Regards

David Bla

Upvotes: 0

Views: 920

Answers (2)

DavidBla
DavidBla

Reputation: 13

I switched to start-job because it allows passing credentials but not using the remoteing feature:

$variable_needs_to_be_passed

$a_job = start-job -ScriptBlock{param($var) Do-Stuff-With-Other-User $var} `
-Arg $variable_needs_to_be_passed -credentials $cred

while((get-job -Id ($a_job.id)).State -eq "Running") {sleep(0.5)}

$return_value = Recieve-Job -Id ($a_job.id)

But its terrible slow compared to running command directly (due to iterative calling) maybe it would be better to call the complete script instead of using it to execute single commands.

To better understand it, this part searches all dns and dhcp servers for a specific client. exemplary code:

if(check_permission){ GetAllDhcpScopes }else{ runas ... GetAllDhcpScopes }
foreach( AllDhcpScopes ){ if(check_permission){ GetDhcpLeases $_ }else{ runas ... GetDhcpLeases $_ }

This was anoying in performance so i started to do a permission_check at the beginning and than run the script normally or starating it as job with higher perms!

Upvotes: 0

gvee
gvee

Reputation: 17171

Invoke-Command allows the passing of credentials.

Invoke-Command -ScriptBlock {
    # put your code here
    Write-Host "Hello World!"
} -Credential (Get-Credential)

Upvotes: 1

Related Questions