PowerShell in Pia: what's different from your laptop
If you write PowerShell for a living, you'll feel at home in Pia's activity editor for about ten minutes. Then something that works fine on your laptop throws a weird error and you'll spend an hour finding out why.
Here's my running list of the things that behave differently inside Pia. None of this is in a manual that I could find. I learned all of it the annoying way.
Checking whether a property exists
On your machine, $obj.someField on a missing field just gives you $null. In Pia it throws a PropertyNotFoundException. This one hit me when updating tickets, because some tickets have no agreement object at all and my script died before it could do anything useful.
What works is asking the object about itself:
# Pia throws if the property isn't there, so check first
if ($ticket.PSObject.Properties['agreement'])
{
# safe to touch $ticket.agreement here
}
I do this for basically any field that might not be present now. It looks fussy and it's the right call.
Error handling in catch blocks
Two things I'd normally reach for don't work in here: reading the response stream with GetResponseStream(), and leaning on $_.Exception.Response.
What's been reliable for me is nested try/catch, grabbing whatever is available:
catch
{
$errMsg = ''
# ErrorDetails usually has the useful API response body
try { $errMsg = $_.ErrorDetails.Message } catch {}
# fall back to the exception text if that was empty
if (-not $errMsg) { try { $errMsg = [string]$_.Exception } catch {} }
Write-Error $errMsg
$activityOutput.success = $false
}
It's ugly. It also means that when an API call fails, I actually see why.
Sort-Object can hand you back a single item
This one is standard PowerShell rather than a Pia quirk, but it bit me in an activity, so it's on the list. If you sort a collection that contains one item, you get the item back instead of an array of one. Then the next line does .Count or indexes into it and everything goes sideways. Wrapping it fixes it:
$sorted = @($items | ForEach-Object { $_ } | Sort-Object { $_.name })
The @( ) around the whole thing is what guarantees you get an array back.
Integration variables come with quotes on them
Any integration variable, and JSON that comes back from some other APIs, can arrive wrapped in literal quote characters. If your auth header is failing and the token looks right, this is the first thing I'd check.
$token = ([string]$token).Trim('"')
I trim anything that came from outside the activity, every time, without thinking about it. The cost of doing it when you didn't need to is zero.
Smaller stuff
- Hyphens in variable names are out. Use underscores.
- If an activity fails without saying anything and you've added
Set-StrictMode -Version Latest, take it out. For me it made one activity fail silently, and the only clue was an error output I'd forgotten to look at. - One built-in activity I use for license assignment crashes on a null compare even when the assignment itself worked. Setting
continue_on_error: 'true'on that task gets past it. Check the license actually landed, though, so you're not just trusting a green checkmark.