Powershell
Hello!
I am creating several powershell scripts that draw on MAs under PAs or a Powershell script that can get affected user from the parent SR.
However My titles do not seem to update and my emails may or may not send depending on how deep it goes.
My scripts are attached - but my question is: How do I get the parent SR from deep under a PA? Also, How do retrieve MAs under a PA? I am using PowerShell
ACs and storing the PowerShell as templates in scsm.
Might be a bit so I highly appreciate any help!
Thanks!
Best Answers
-
Geoff_Ross Cireson Consultant O.G.
Hi Ryan,
You need a recursive function to get the ultimate parent if you have nesting.
Function Get-ParentWI { Param ( $Activity, [string]$ComputerName ) $SCSM = @{ ComputerName = $ComputerName } #Get Parent of this Activity $WIContainsActivityRel = Get-SCSMRelationshipClass "System.WorkItemContainsActivity" @SCSM $ParentWI = (Get-SCSMRelationshipObject -TargetObject $Activity -TargetRelationship $WIContainsActivityRel @SCSM).SourceObject If ($ParentWI -eq $null) { # We've reached the top - Return Original Actvity Return $Activity } Else { # Parent is not confrmed as the root, and thus, we will loop into another "Get-ParentWI" function. Get-ParentWI -Activity $ParentWI @SCSM } }
Then you can call the function and it will keep calling itself until the top level parent is found.
Get-Parent -Activity $myActivity -ComputerName "test server"
Geoff
0 -
Simon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭
@Ryan_Kelley When I use this command, version 1.0.2016.0 is shown.
So I guess you have an older version installed, where the get-scsmrelationshipobject command is not working with this set of parameters.
Try installing the latest version of smlets on your servers and I am sure it will work then
1 -
Simon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭
The error lies here:
$parentSR = Get-SCSMRelationshipObject -ByTarget $myActivity -Relationship $rel -Recursive:$true | Where-Object {$_.SourceObject.ClassName -eq 'System.WorkItem.ServiceRequest'} | Select-Object -First 1
You receive the relationship object here and not the SourceObject. You filter on the service request class, but the $parentSR variable contains the relationship object - so this is the $parentSR.guid.id ;-)
if you write
$parentSR = (Get-SCSMRelationshipObject -ByTarget $myActivity -Relationship $rel -Recursive:$true | Where-Object {$_.SourceObject.ClassName -eq 'System.WorkItem.ServiceRequest'} | Select-Object -First 1).sourceobject
you receive back the SR and then you should be able to receive the full object with
$parentSR = Get-SCSMObject -Id $parentSR.Id.Guid
And as I mentioned before, RelationshipSource- and Targetobjects NEVER contain the full object. You can either receive the object via
Get-scsmobject -id $parentSR.id
or you access the values via e.g.
$parentSR.Values.Item($parentSR.Values.Type.Name.IndexOf("Title")).Value)}
0 -
Simon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭
may I ask why you set the $parentSR to the Sourceobject again in this code snippet
$parentSR = Get-SCSMObject -Id $parentSR.Id.Guid if ($null -eq $parentSR) { Write-Output "Parent Service Request not found." exit 1 } else { $parentSR = $parentSR.SourceObject }
First you assign the SR Object to the variable, and afterwards you assign the SourceObject of the ServiceRequest object (which is NULL) to it - therefor the $parentSR is null and generates the error you received. After you recieved the SR with
$parentSR = Get-SCSMObject -Id $parentSR.Id.Guid
there is no need to use Sourceobject because you already have the full ServiceRequest object and it is also assigned to the $parentSR variable :)
So just rewrite it to
$parentSR = Get-SCSMObject -Id $parentSR.Id.Guid if ($null -eq $parentSR) { Write-Output "Parent Service Request not found." exit 1 }
and it will work fine ;)
0
Answers
@Ryan_Kelley
Getting the parent SR is actually pretty easy, even if the Activity is inside one or more other activities:
This returns the parentSR as SourceObject, means it is not possible to retrieve all fields (like Title or so) directly like you would do it for a normal SCSM object - Source and Target Objects from Relationshipobjects work a bit different here. There are two options though:
If you use the second option, you can paste every field you need inside the "IndexOf(...)", be careful though as this is CASE SENSITIVE. If you paste the name of a field, which is an enumeration, you will receive the enumeration directly, so if you need thee enumeration name or displayname, you have to declare that as well.
The source -or targetobjects can be used without limitations to get or set relationships though.
edit: if you want to receive the parentSR in a powershell activity, then you can do the following.
Do not use the parentId as parameter, use the activityId. and then use the code as shown below:
Inside the PSA template you have to map the activity Base Id inside the activityId parameter.
Hello,
Sorry for the late reply -- was on PTO.
Objective is to send an email to the affected user's UPN within AD. But I cannot retrieve the parentid and thus cannot find the affected user.
SR -> PA -> SA -> AC
My code below trying to use the powershell did not work as expected still cannot find the parentid:
The output below is:
Active Directory module imported.
Failed to retrieve the parent service request: Parameter set cannot be resolved using the specified named parameters.
also within the powershell script part of the AC template I use powershell param -> property -> activity base id. I tried with parent base id with similar results.
Thank you for any help that can be provided! :)
script:
Hi Ryan,
You need a recursive function to get the ultimate parent if you have nesting.
Then you can call the function and it will keep calling itself until the top level parent is found.
Geoff
Hello! Thank you for answering so quickly(on a sunday!)! Good news I can get the SA now but It does not go further than that.
And thank you again for an help! It is appreciated as I continue to learn smlets!
error:
An error was written to the Error stream!
Parameter set cannot be resolved using the specified named parameters.
An error was written to the Error stream!
Parameter set cannot be resolved using the specified named parameters.Cannot bind parameter 'Id'. Cannot convert value "SA1014256" to type "System.Guid". Error: "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."
Active Directory module imported.
Failed to retrieve the Service Request object using the ultimate parent WI ID.
script:
added code below
Ryan,
Its hard to read your script. Can you please edit the post and inset a code block and paste it there rather than in a paragraph.
Something is expecting a guid and is getting the SA is "SA1014256" instead. I can't see what would be doing this. Try pasting your script into PowerShell ISE (with a provided parameter) and you will get a better error.
Geoff
Sorry here it is in a code block and thank you for your help! I modified it a bit and now am just getting the:
An error was written to the Error stream!
Parameter set cannot be resolved using the specified named parameters.
Active Directory module imported.
The ultimate parent is not a Service Request or was not found.
Which means the recursive function appears to not be able to find the service request parent - I think.
@Ryan_Kelley
the problem is, forgot the
in your first code. Can you try it that way and tell me if it worked
Add recursive but - code still ends with: Failed to retrieve the parent service request: Parameter set cannot be resolved using the specified named parameters. Per Simon_Zeinhofer I used the first code.
Thank you all for any help! I feel like I might be answering other peoples questions - who might be wanting to do do more advanced workflows. My test workflow SR-> PA-> SA-> AC(powershell).
I also set the bottom to activity or parent id and get the same results:
One error in the script, and that's my fault, it has to be written:
sorry for this. Still I don't get why it errors out. for me it works, even when I don't use the recursive parameter at all. And I have SR -> SA -> PA -> AC in my test request as well.
I guess this script runs on your workflow server? Are smlets installed on this server? If yes, can you outcomment this code.
It shouldn't be necessary then.
Thank you for helping and any insight - (I agree am am at a loss as to why I cannot get the SR's affected user)!
I added the -Recursive:$true
But still it only got to: Failed to retrieve the parent service request: Parameter set cannot be resolved using the specified named parameters.
I only use: $GLOBAL:smdefaultcomputer = "testserver" - as a reminder as to which script is pointing where. Helpful sometimes for me :) when I use different modules and they all need to point to different places.
Smlets is installed on the test box and in prod. I have the issue with both. Smlets version: 1.0.0.
When you type in the following command into smlets, what do you receive back when you open an ISE on your workflow server?
What version of SCSM do you have installed?
For our test box it does not have access to the internet for the most part so I use the command:
If I need to install anything I download it manually then install it.
Results:
@Ryan_Kelley When I use this command, version 1.0.2016.0 is shown.
So I guess you have an older version installed, where the get-scsmrelationshipobject command is not working with this set of parameters.
Try installing the latest version of smlets on your servers and I am sure it will work then
Great spot Simon. Yes, get the latest version and probably everything will work.
Thank you all for your help! I would never had guessed we were out of date! I updated smlets in our test environment(eventually prod). The service request has been found! If possible:
The code below gets the parentSR but I cannot seem to find any usertexts. Is there something else I need to add? I am trying to pull them in based on delimitators but if that fails just add the entire line. And Again thank you both @Geoff_Ross and @Simon_Zeinhofer for your help! Right now the script creates an SR but does not contain anything and the error says:
Active Directory module imported.
Found Service Request: SR000001
Affected User: user
User's UPN:email
UserText5 is null, empty, or whitespace. Cannot determine restricted or other countries to visit.
An error occurred on line 0: You cannot call a method on a null-valued expression.
An error occurred on line 0: A parameter cannot be found that matches parameter name 'RelationshipClass'.
New Service Request Created with ID: SR000001
Ryan,
Sometimes the relationship cmdlets don't return the full SR object. Try
before trying to get the UserText as that will get the whole SR.
Thank you! I added the line after:
Ticket does not contain the usertexts and also no title nor affecteduser -fun problem - maybe :)
but it still errored:
An error was written to the Error stream!
An object of class EnterpriseManagementObject with ID ee3b7bb2-c1f3-b77c-d52d-779078ab41e0 was not found.
An error was written to the Error stream!
An object of class EnterpriseManagementObject with ID ee3b7bb2-c1f3-b77c-d52d-779078ab41e0 was not found.You cannot call a method on a null-valued expression.
@Ryan_Kelley
The error lies here:
You receive the relationship object here and not the SourceObject. You filter on the service request class, but the $parentSR variable contains the relationship object - so this is the $parentSR.guid.id ;-)
if you write
you receive back the SR and then you should be able to receive the full object with
And as I mentioned before, RelationshipSource- and Targetobjects NEVER contain the full object. You can either receive the object via
or you access the values via e.g.
I cannot emphasize how much I am learning and how much I am grateful for the assistance!
I implemented the change but it now just says: Cannot bind argument to parameter 'SMObject' because it is null.
Took out the try and catches as they may have been causing issues.
@Ryan_Kelley
may I ask why you set the $parentSR to the Sourceobject again in this code snippet
First you assign the SR Object to the variable, and afterwards you assign the SourceObject of the ServiceRequest object (which is NULL) to it - therefor the $parentSR is null and generates the error you received. After you recieved the SR with
there is no need to use Sourceobject because you already have the full ServiceRequest object and it is also assigned to the $parentSR variable :)
So just rewrite it to
and it will work fine ;)