0

I am writing a binary cmdlet and I would like to accept a PSCredential parameter in order to use elevated credentials.

[Parameter]
public PSCredential Credential { get; set; }

There seems to be a distinct lack of documentation for this - all I can find is how to execute PowerShell cmdlets from C#, which is not what I wish to do.

I downloaded the SimpleImpersonation nuget package to avoid doing the Windows impersonation myself.

using (Impersonation.LogonUser("GLOBAL", "last.first", "mypassword", LogonType.Interactive))
{
    foreach (ServerInfo server in Targets)
        ProcessRecord();
}

When I check System.Security.Principal.WindowsIdentity.GetCurrent().Name the user is correct, but when I execute a command (eg ServerManager.OpenRemote(computerName)) I receive an UnauthorizedAccessException. If I run this code from a PowerShell instance running as the desired user the cmdlet executes flawlessly.

Does anyway have any clues as to how to utilise a PSCredential in a C# binary cmdlet?

1 Answer 1

2

I'm not sure why this has so little documentation online. As I suspected I needed to use impersonation to accomplish this. There seems to be a lot of plumbing involved with this, see here.

After some more investigation there's a nice nuget package called SimpleImpersonation.

Using:

[Parameter]
public PSCredential Credential { get; set; }

I can do this:

using (Impersonation.LogonUser("GLOBAL", Credential.UserName, Credential.Password, LogonType.Interactive))

This allows me to run commands as the impersonated user. LogonUser() takes the username and SecureString password.

This works fine for ServiceController calls, but ServerManager was still throwing COM unauthorised exceptions. I managed to find this post which said to not use OpenRemote() but to use a ctor overload. The following code works:

using (ServerManager serverManager = new ServerManager(@"\\server\c$\windows\system32\inetsrv\config\applicationHost.config"))
{
    ApplicationPoolCollection appPool = serverManager.ApplicationPools;
    Console.WriteLine(appPool.Count);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.