Error when executing Get-SCSMClass in SMA Powershell script
Every now and then I get a weird error when executing a script in SMA that otherwise runs without issues. I'm suspecting an intermittent concurrency issue, but I have no idea how to circumvent it.
My script then fails on the instruction
$ActivityClass = Get-SCSMClass System.Workitem$ -ComputerName $ComputerName
The error i'm getting is:
Get-SCSMClass : Item has already been added. Key in dictionary: 'HQSCSMMS01.multi.be_ENU' Key being added: <br>'HQSCSMMS01.multi.be_ENU'<br>At line:11 char:18<br>+ ... vityClass = Get-SCSMClass System.Workitem$ -ComputerName $ComputerNam ...<br>+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br> + CategoryInfo : InvalidOperation: (HQSCSMMS01.multi.be:String) [Get-SCSMClass], ArgumentException<br> + FullyQualifiedErrorId : GenericMessage,SMLets.GetSMClassCommand<br>
I tried without the -Computername parameter, but then I get another error:
Get-SCSMClass : The Data Access service is either not running or not yet initialized. Check the event log for more information.
Best Answer
-
Stephane_Bouillon Customer Advanced IT Monkey ✭✭✭This code seems to get around the problem:
$ComputerName = 'myServer'<br>Import-Module SMLets<br>$incidentClass = Get-SCSMClass -Name "system.workitem.incident$" -ComputerName $ComputerName<br>If(-not $incidentClass)<br id="null">{<br> Write-Output "Problem with PS module"<br> Import-Module SMLets<br> $IncidentClass = Get-SCSMClass -Name 'System.WorkItem.Incident$' -ComputerName $Computername<br>}
subsequent code in the script runs without further errors. In the automation logs I see that from time to time I get the PS module error message.
0
Answers
- What version of SCSM are you running, and what version of SMLets? Same version of SMA as SCSM?
- Do you receive this error if you specify the -Name parameter? (e.g.: Get-ScsmClass -ComputerName myScsmServer -Name System.WorkItem$)
There are two issues here I am trying to either confirm or rule out: 1.) SMA does seem to behave strangely when parameters are supplied by position rather than by naming the parameter, even if the same command works perfectly well in a PS window, and 2.) the fact that your error message mentions trying to add something as part of a "get" command makes me suspect something fundamentally wrong such as a version incompatibility of some kind.You are right to specify the -ComputerName param. Otherwise, it assumes the local machine is what you are trying to talk to, and on an SMA server or your own computer, it is likely not running the Service Manager DAS service as your error correctly indicates.
I'll add the -Name parameter to the command and see if that helps
Regarding your question: I'm running System Center 2016 SCSM Version 7.5.7487.0
SMLETS version 0.5.0.1
Triggering multiple scripts concurrently should not cause you any problems unless they are creating data in SCSM, and even then it should only be an issue if one instance expects data that has since been changed by another. I do not think it is likely that this is your issue, but I suppose anything is possible.
I have definitely had issues with cmdlets in SMA Scripts if the parameters aren't explicitly named for some reason, so I hope that is your problem. There is a decent chance of it. I have never determined why this matters, but it is repeatable, and simple enough to work with.
Unfortunately I still get the same error.
What I noticed in the logs is that it usually fails when the same script was run shortly before it.(which finished successfully).
I'm now looking more towards finding a workaround when it actually fails. Does anyone have suggestions ?
I am glad @Justin_Workman has jumped in here, because this might be beyond what I can help with. One last suggestion though, and then a tip:
Perhaps it is not the act of getting a class that is failing, but rather you are seeing the affects of another cmdlet in the same error stream? This is a bit of a stretch, but I'll continue the thought just in case. Are there any other parts of your script that create/modify objects or relationships, perhaps later in the script that actually cause this error to occur in the previous run?
I can at least offer this (completely optional) tip based off of Justin's comment, which helps reduce re-typing:
This is an example of "splatting" which I use in most scripts that use SMLets, particularly when I have to also supply a credential in addition to the server name. It's shorthand, but can also help prevent errors of omission. It also cleans up the script a bit.
Short of this, if you could try inline scripting the SMA runbook against a management server (where the console and smlets are presumably installed by virtue of the Cireson Portal) I'd be interested to know the results.
But In terms of how this changes the runbook execution, per what @Justin_Workman it sounds like the $computername is a hashtable instead of just a string. Whichever the case, I'd go back to using the -computername parameter followed by a string variable set near the beginning of your script. Here's an example of how I begin a lot of my scripts/runbooks with SMLets:
This also serves the purpose of making fairly adaptable/shareable scripts since there is now only one place folks need to actually set their management server.
The alternative to this which wouldn't require using -computername at all is to create a runbook in SMA that has an inlinescript to your SCSM server. This approach is the same as running the powershell directly on the box hence you don't need the -computername parameter. In order to achieve this, you'll need to create an SMA Asset that contains the username/password of a user that has the rights to log into that box and perform SCSM actions. You could use the SCSM Service Account or create a wholly new service account that is a local admin on the scsm mgmt server and an admin within SCSM. The advantage of this being that when it comes to Work Item history logs there is a clear distinction of "what SMA did"
On the other hand, I'm curious as to know a method for converting a hashtable into a string or more strictly control how this error occurs if that is the cause ? Another question is if a try/catch approach would help ?
To answer your question more directly, you want to end up with an array of computer names that is provided to your -ComputerName param, not a hashtable of them. An array, in terms of text, is just a comma-separated list. A hashtable is an array of key/value pairs, which is not what the cmdlet is expecting as input. There are ways to split and join your hashtable to condition it.
subsequent code in the script runs without further errors. In the automation logs I see that from time to time I get the PS module error message.