Please share any images or screenshots, if relevant.
All variable which we send from running powershell rule like AccountRequest are showing empty in powershell rule. Even though powershell getting called. We are using 8.3p3 and we are windows 2022 , it is working on windows 2012
Please share any other relevant files that may be required (for example, logs).
Share all details about your problem, including any error messages you may have received.
We are using windows 2022 and calling powershell from rpcservice , no error showing in iiq logs but when it call powershell rule, none of the vairbale like $env or account request or below attribute having any value. it seems all the content are removed.
Note : Same thing working on windows 2012
$sReader = New-Object System.IO.StringReader([System.String]$env:Request);
$xmlReader = [System.xml.XmlTextReader]([sailpoint.Utils.xml.XmlUtil]::getReader($sReader));
$requestObject = New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader);
$resultObject = New-Object Sailpoint.Utils.objects.ServiceResult;
This is almost always about how IQService is launching PowerShell on that Windows 2022 box (path/bitness), version mismatches, or policy/PowerShell-mode changes that prevent the expected environment variables from being injected.
Below is a focused “find & fix” runbook you can execute end-to-end. I’ve put the highest-probability fixes first.
1) Confirm you’re really launching Windows PowerShell 5.1 (64-bit)
IdentityIQ’s RPCService/IQService populates the request into process environment variables (e.g., $env:Request) and, for non-OO scripts, creates SP_* variables. This is explicitly how IQService is designed to pass the AccountRequest/XML to your PowerShell script. (Running Powershell directly via the IQService, Writing a Script)
On Windows Server 2022, some hosts have PowerShell 7 installed and in PATH earlier than Windows PowerShell 5.1. If your rule calls a generic powershell.exe (or even pwsh) incorrectly, you can end up in the wrong host, or the 32-bit subsystem.
What to do (on the IQService host):
In your PowerShell Rule (or connector rule), call the absolute 64-bit path:
(Do not rely on PATH.) SailPoint’s own troubleshooting notes recommend using the absolute path to PowerShell to avoid PATH/host confusion. (Troubleshooting)
Avoid SysWOW64 (that’s 32-bit). If IQService or your script somehow hits C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe, the environment injection may not line up with your script expectations.
Quick verification snippet (drop at the top of your PS rule/script):
You want PSVersion 5.1.x, Is64BitProcess = True, and the path under System32.
2) Make sure IQService version matches your IdentityIQ version/patch
IQService must match the IdentityIQ server version (including patches). An out-of-date IQService on a newer OS (Server 2022) can behave oddly, including failing to inject the process environment block expected by your script. Re-installing the current IQService build that matches your IIQ patch often resolves “vars not there” symptoms. (Install and Register the IQService for Use with Windows)
Also note SailPoint continues to update IQService (even recently), so grabbing the latest for your major/minor and re-registering can help—especially on newer OS builds like Windows Server 2022. (Introduction to IQService)
3) Prove the env injection path works (no IIQ involved)
Run this on the IQService host in an elevated Windows PowerShell 5.1 console:
# Simulate what IQService does
$env:Request = "<AccountRequest><nativeIdentity>dummy</nativeIdentity></AccountRequest>"
# Your parsing code (unchanged)
$sReader = New-Object System.IO.StringReader([string]$env:Request)
$xmlReader = [System.Xml.XmlTextReader]([sailpoint.Utils.xml.XmlUtil]::getReader($sReader))
$requestObject= New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader)
$resultObject = New-Object Sailpoint.Utils.objects.ServiceResult
$requestObject | Format-List * # Should NOT be empty
$env:Request.Length # Should show a non-zero value
If $env:Request shows a value here, your parsing code is fine. Your problem is therefore how IQService is launching PowerShell (step 1) or the IQService build (step 2).
If it fails with .Utils types not found, ensure your script is executed in the same way IQService runs it (object-oriented example from the wiki assumes the SailPoint client types are available to the process launched by IQService). The wiki and docs outline how that request is provided and parsed in OO vs non-OO styles.
4) Check for Constrained Language Mode (CLM) / WDAC
On hardened Server 2022 builds with Windows Defender Application Control / Device Guard, PowerShell can be forced into ConstrainedLanguage. That can block New-Object with custom types and assembly usage (your Sailpoint.Utils.objects.* calls). Even if $env:Request exists, object creation silently fails and your downstream objects end up $null, which looks like “the content is removed”.
Test:
$ExecutionContext.SessionState.LanguageMode
If you see ConstrainedLanguage, ask security to allow this script path/signing policy or run the script in FullLanguage context for IQService. (This is a Windows policy issue, not SailPoint.) Microsoft’s CLM restricts .NET type usage.
5) Verify the rule is not spawning a child process that loses the env
IQService populates the environment of the process it launches. If your rule/script immediately calls Start-Process, Invoke-Command, or remotes to another session, that child context won’t have the injected $env:Request unless you explicitly pass it.
If you must spawn, pass the data explicitly, e.g.:
Or avoid spawning—do the work in the original process that IQService started.
6) Try the non-OO variable names as a sanity check
IQService also creates environment variables in the form SP_<OPERATION>_<NAME> and SP_APP_<NAME> for non-OO scripts. Quick smoke test at the script start:
Get-ChildItem Env: | Where-Object Name -like 'SP_*' | Sort-Object Name
$env:SP_NativeIdentity
If none of these exist either, it strongly points to PowerShell host mismatch or IQService not injecting (steps 1 & 2).
7) Turn on IQService troubleshooting basics
Confirm IQService logs and that your rule actually triggers on 2022.
Double-check PowerShell path configured in your rule; SailPoint docs explicitly suggest trying the absolute powershell.exe path during troubleshooting.
Ensure network/TLS changes in newer IQService builds aren’t blocking the script call (recent IQService versions enforce TLS defaults). (Installing and Registering IQService)
8) Known-good sample (minimal dump)
Add this at the top of the script to capture state the moment IQService launches it:
"=== IQService PS Host Info ==="
$PSVersionTable
"64-bit? " + [Environment]::Is64BitProcess
"PSHOME : $PSHOME"
"Proc : " + (Get-Process -Id $PID).MainModule.FileName
"=== Language Mode ==="
$ExecutionContext.SessionState.LanguageMode
"=== Env smoke ==="
"REQUEST length : " + (($env:Request).ToString()).Length
Get-ChildItem Env: | Where Name -like 'SP_*' | Sort Name
If REQUEST length is 0 and there are no SP_* variables, you’re not in the intended process (wrong PowerShell path/bitness) or IQService didn’t inject due to version/policy issues.
Why this worked on Windows 2012 but not on 2022
Newer servers often have PowerShell 7 alongside 5.1; PATH differences and service redirection (32-bit vs 64-bit) pop up during migrations.
Security baselines on 2022 frequently enable Application Control → ConstrainedLanguage. That breaks your New-Object usage and makes it look like nothing comes through.
Older IQService builds may not play nicely on newer OSes; SailPoint requires matching IQService/IIQ versions and recommends the absolute PowerShell path for script launching. (Install and Register the IQService for Use with Windows)
Upgrade/reinstall IQService to match your IIQ patch on that 2022 host.
Check LanguageMode; if ConstrainedLanguage, get an allow policy for the script/assemblies or run in FullLanguage.
Run the env dump snippet above and confirm $env:Request length > 0 and/or SP_* variables appear. If they do, your original parsing code will work as on 2012
I have validate all the thing , Language mode is fulllanguage, and other parameter also same.
Even i can see $env.Request is showing once i have added complete powershell.exe path which is mentioned.
I am still seeing the problem when we use below line as it always show null,nothing printing it seems New-Object not working properly. So let us know what else we can check. We have 8.3p3 so everything is compatible as well. So let us know what else we can check
$sReader = New-Object System.IO.StringReader([string]$env:Request)$xmlReader = [System.Xml.XmlTextReader]([sailpoint.Utils.xml.XmlUtil]::getReader($sReader))$requestObject= New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader)
If $env:Request is now definitely populated (after forcing the full 64-bit powershell.exe path) but $requestObject stays $null, the usual culprit is that the SailPoint Utils assembly isn’t actually loaded in that PowerShell process on your Windows 2022 host. On older hosts it’s easy to “get lucky” because of working-directory/probing behavior; on 2022/.NET 4.8 you often have to explicitly load Utils.dll before you can New-Object Sailpoint.Utils.objects.AccountRequest(...). SailPoint’s own samples show doing exactly that with Add-Type -Path ...\Utils.dll. (Writing a Script)
Below is a tight, copy-paste block that (1) resolves the actual IQService install directory, (2) unblocks and loads Utils.dll, (3) sanity-checks the types are visible, and (4) constructs the objects without using the XmlUtil helper (to avoid one more dependency while we debug):
# Fail fast and log real errors (IQService can swallow non-terminating errors otherwise)
$ErrorActionPreference = 'Stop'
# 1) Find IQService home and Utils.dll robustly from the service definition
$svc = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\IQService' -Name ImagePath
$svcPath = ($svc.ImagePath -replace '^"|"$','') # strip quotes
$iqHome = Split-Path $svcPath # e.g. C:\SailPoint\IQService
$utils = Join-Path $iqHome 'Utils.dll'
# 2) Unblock and load Utils.dll (unsigned/“downloaded” DLLs can be blocked on 2022)
if (Get-Item $utils -Stream Zone.Identifier -ErrorAction SilentlyContinue) { Unblock-File $utils }
Add-Type -Path $utils
# 3) Prove the SailPoint types are now visible
if (-not [Type]::GetType('Sailpoint.Utils.objects.AccountRequest', $false)) {
throw "Sailpoint.Utils.objects.AccountRequest type not visible. Loaded from: $utils"
}
# 4) Build readers without XmlUtil to reduce moving parts while debugging
$sReader = New-Object System.IO.StringReader([string]$env:Request)
$xmlReader = New-Object System.Xml.XmlTextReader($sReader)
# 5) Construct the request/result objects
$requestObject = New-Object 'Sailpoint.Utils.objects.AccountRequest' ($xmlReader)
# Optional: dump a quick proof
"Request XML length: $([string]$env:Request).Length"
"RequestObject type : " + ($requestObject.GetType().FullName)
Why this usually fixes it
Utils.dll must be loaded for those Sailpoint.Utils.* types to exist. Without it, New-Object has nothing to construct and—depending on error handling—can look like “it returns null”. SailPoint’s samples and docs explicitly Add-Type -Path ...\Utils.dll before using AccountRequest/ServiceResult.
On Server 2022/.NET 4.8, default probing is less forgiving. If the PS working directory isn’t the IQService bin (very common when you hard-pin the powershell.exe path), the assembly won’t auto-resolve, so explicit path loading is required. (SailPoint docs and community threads show Add-Type -Path "C:\SailPoint\IQService\Utils.dll" patterns.) (Powershell script : Accessing attributes within accountRequest)
Run these quick probes to pinpoint the exact failure:
# 1) Is the SailPoint assembly actually loaded?
[AppDomain]::CurrentDomain.GetAssemblies() | Where-Object FullName -match 'Utils' |
Select-Object FullName, Location
# 2) Do we see the types?
[AppDomain]::CurrentDomain.GetAssemblies() |
ForEach-Object { $_.GetTypes() } |
Where-Object FullName -like 'Sailpoint.*' |
Sort-Object FullName
# 3) Does the XML parse natively? (rule out truncation/bad XML)
try { [xml]$reqXml = $env:Request; $reqXml.DocumentElement.Name } catch { $_ | fl * -Force; throw }
# 4) How big is Request? (environment vars over ~32K can get you into trouble)
([string]$env:Request).Length
If (1)/(2) show no SailPoint types, the assembly is not loading (wrong path, blocked DLL, or policy).
If (3) fails, your request XML is malformed/truncated (less likely now that $env:Request prints, but worth checking).
If (4) shows a very large value (tens of thousands of chars), you may be bumping environment-block limits; consider a non-OO fallback (use the SP_* request variables, which IQService emits for non-OO scripts) to avoid parsing the full XML. (Before After Script)
Bonus: keep XmlUtil if you prefer it
Once Utils.dll is loading cleanly, you can go back to your original style:
(But verify the type exists first; the reflection snippet above will tell you.)
TL;DR
On Windows 2022, explicitly load Utils.dll before New-Object Sailpoint.Utils.objects.AccountRequest(...), ensure the DLL isn’t blocked, and confirm the types are visible—then your existing code will work the same as it did on 2012. SailPoint’s docs and examples show this Add-Type -Path ...\Utils.dll step as required.
If you paste the output of the 4 probe snippets (assemblies/types/XML/length), I’ll tell you exactly which link in the chain is breaking.