如何为PowerShell进程设置RPC_C_IMP_LEVEL_IMPERSONATE模拟级别?
I get it—you're stuck trying to raise the RPC impersonation level for your PowerShell process to RPC_C_IMP_LEVEL_IMPERSONATE, since the C++ CoInitializeSecurity approach you found relies on a main function which doesn't translate directly to PowerShell. Let's fix that by using P/Invoke directly in PowerShell to call the same API.
First, let's recap the issue you're facing:
调用服务时出现以下错误:
Either a required impersonation level was not provided, or the provided impersonation level is invalid.
且从*.log文件中发现当前模拟级别为Identification。
Here's a working PowerShell script that sets the impersonation level correctly. We'll define the necessary enums and P/Invoke signature, then call CoInitializeSecurity early in your process (it can only be called once per process, so run this at the start of your script):
# Define the necessary enumerations and constants Add-Type @" using System; using System.Runtime.InteropServices; public enum RpcAuthnLevel { Default = 0, None = 1, Connect = 2, Call = 3, Pkt = 4, PktIntegrity = 5, PktPrivacy = 6 } public enum RpcImpLevel { Default = 0, Anonymous = 1, Identify = 2, Impersonate = 3, Delegate = 4 } public enum EoAuthnCap { None = 0x00000000, MutualAuth = 0x00000001, StaticCloaking = 0x00000020, DynamicCloaking = 0x00000040, AnyAuthority = 0x00000080, MakeFullSIC = 0x00000100, Default = 0x00000200, SecureRefs = 0x00000002, AccessControl = 0x00000004, AppID = 0x00000008, Dynamic = 0x00000010, RequireFullSIC = 0x00000200, AutoImpersonate = 0x00000400, NoCustomMarshal = 0x00000800, DisableAAA = 0x00001000 } public class Ole32 { [DllImport("ole32.dll", SetLastError = true)] public static extern int CoInitializeSecurity( IntPtr pVoid, int cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1, RpcAuthnLevel dwAuthnLevel, RpcImpLevel dwImpLevel, IntPtr pAuthList, EoAuthnCap dwCapabilities, IntPtr pReserved3); } "@ # Set the apartment state to STA (required for many COM operations) [System.Threading.Thread]::CurrentThread.ApartmentState = [System.Threading.ApartmentState]::STA # Call CoInitializeSecurity to set the impersonation level to Impersonate $result = [Ole32]::CoInitializeSecurity( [IntPtr]::Zero, -1, [IntPtr]::Zero, [IntPtr]::Zero, [RpcAuthnLevel]::None, [RpcImpLevel]::Impersonate, [IntPtr]::Zero, [EoAuthnCap]::None, [IntPtr]::Zero ) # Verify the call succeeded (0 means success) if ($result -ne 0) { Write-Error "CoInitializeSecurity failed with error code: $result" } else { Write-Host "Successfully set RPC impersonation level to Impersonate" }
Key Notes:
- Apartment State: We set the thread to STA (Single-Threaded Apartment) first, which is a common requirement for COM-based operations that rely on impersonation.
- CoInitializeSecurity Call: The parameters mirror the C++ code you provided:
- We pass
[IntPtr]::Zerofor most unused parameters (like authentication services list) dwAuthnLevel.Nonemeans no authentication is required (adjust this if your service requires specific auth)dwImpLevel.Impersonateis the critical setting that fixes your error
- We pass
- Single Call: Remember that
CoInitializeSecuritycan only be called once per PowerShell process. If you run this script multiple times in the same session, the second call will fail—so make sure this runs at the very start of your workflow.
After running this script, try calling your service again. The error about missing/invalid impersonation level should be resolved, and your log files should show the impersonation level as Impersonate instead of Identification.
内容的提问来源于stack exchange,提问作者isxaker

