Home > Back-end >  Need to run commands within a Powershell script as different user
Need to run commands within a Powershell script as different user

Time:08-25

I need to work on a fairly complicated script that involves multiple service accounts to different APIs and for the most part, the script works fine but I'm running into an issue that's bugging me like crazy. I can't run the script as a different user because the powershell running the node can only run the script as NT Authority.

So a part of my script looks like this:

Foreach ($i in $AllUsers) {
   $ConID = (Get-ADUser -Identity $i -Properties ExtensionAttribute2 -Credential $svcPOSHCreds).ExtensionAttribute2
   $ConDN = (get-aduser -filter {EmployeeID -eq $ManagerEID} -Credential $svcPOSHCreds).DistinguishedName
   Set-ADUser -Identity $i -Manager $ConDN-Credential $svcPOSHCreds
   Get-ADPrincipalGroupMembership $i -Credential $svcPOSHCreds | foreach {Remove-ADGroupMember $_ -Members $i - Confirm:$false -Credential $svcPOSHCreds}
   Add-ADGroupMember -Identity 'Identity Con User' -Members $i -Credential $svcPOSHCreds
}

As you can see, I have to specify -Credential for every command I run because the user running this script doesn't have the rights to do some of the stuff.

So far I can count roughly 108 "-Credential" parameters to all of the commands between different APIs and AD...etc.

Is there a way that I can group the commands together so they utilize the same "Credentials" so I don't have to specify it each time when I run each command? I cannot specify how the script will be ran :( My limit is only to the inside of the PS1! so no "runas"...etc.

CodePudding user response:

Is there a way that I can group the commands together so they utilize the same "Credentials" so I don't have to specify it each time when I run each command?

Yes, you can use the preference variable $PSDefaultParameterValues to automate this process.

Here is a simple example to demonstrate how it works, first we can define to test functions:

function Set-Something {
    [CmdletBinding()]
    param([pscredential] $Credential, [string] $SomeParam)

    [pscustomobject]@{
        SomeParam  = $SomeParam
        UserName   = $Credential.UserName
        Password   = [Net.NetworkCredential]::new('', $Credential.Password).Password
    }
}

function Get-Something {
    [CmdletBinding()]
    param([pscredential] $Credential, [string] $SomeParam)

    [pscustomobject]@{
        SomeParam  = $SomeParam
        UserName   = $Credential.UserName
        Password   = [Net.NetworkCredential]::new('', $Credential.Password).Password
    }
}

And for these 2 functions we will set their -Credential parameter as a Default Parameter:

$cred = [pscredential]::new('hello', (ConvertTo-SecureString 'world' -AsPlainText))

$PSDefaultParameterValues = @{
    'Set-Something:Credential' = $cred
    'Get-Something:Credential' = $cred
}

Then we can test if it works correctly, here we can assume that the $cred variable will be passed as default to both functions:

Get-Something -SomeParam 123
Set-Something -SomeParam 123

The result is:

SomeParam UserName Password
--------- -------- --------
123       hello    world
123       hello    world

You can also use wildcards here, so for example:

$PSDefaultParameterValues = @{
    '*-Something:Credential' = $cred
}

Would target all functions with noun Something.

  • Related