Home Powershell

Set-scsmobject with nested enum

Sarah_GeihsSarah_Geihs Customer IT Monkey ✭

Hi everybody,

I wrote a little powershell skript to set the field 'UseCase' for a few HardwareAssets.

The skript collects the given hardwareasset and try to set the enum 'UseCase' with Set-SCSMObject.

First I got this error which I dont understand:

PS C:\Users\sgeihsadmin> 

Set-SCSMObject -SMObject $hwasset -Property UseCase -Value ENUM.MDM.Projekte.DigiLeih

Set-SCSMObject : Could not find 'ENUM.MDM.Projekte.DigiLeih' in enumeration ''. Allowed values are:

...

'ENUM.MDM.Projekte.DigiLeih' (Enum.d252c5dec3f44fcba1c38c23a7709796)

'' (ENUM.MDM.Projekte.MZEB)

'' (ENUM.MDM.Projekte.HoT)

'' (ENUM.MDM.Projekte.ZebraScan)

'' (ENUM.MDM.Projekte.ASIC)

'' (ENUM.MDM.Projekte.BioBank)

'' (ENUM.MDM.Projekte.Comunicare)

'' (ENUM.MDM.Projekte.Heartbeat)

'' (ENUM.MDM.Projekte.MedFak_DEK)

'' (ENUM.MDM.Projekte.Clarius)

'Positivitätstraining' (Enum.ba7480a9a4d648c5b6788c39a71096b7)

'Logopädie' (Enum.bdd8bbdce1644987b702465dcfbdb553)

'' (ENUM.MDM.Projekte.SoSciSurvey)

...

At line:2 char:1

+ Set-SCSMObject -SMObject $hwasset -Property UseCase -Value ENUM.MDM. ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  + CategoryInfo     : ObjectNotFound: (ENUM.MDM.Projekte.DigiLeih:String) [Set-SCSMObject], ArgumentException

  + FullyQualifiedErrorId : Could not assign enum ,SMLets.SetSMObjectCommand


After a while I got this code:

Import-Module SMLets

$server = '...'

$hwassets = '...'

$HardwareAssetClass = Get-SCSMClass -Name Cireson.AssetManagement.HardwareAsset -ComputerName $server

$filter='HardwareAssetID -eq '+$hwassets

$hwasset=Get-SCSMObject -Class $HardwareAssetClass -Filter $filter -ComputerName $server

$rootEnum =Get-SCSMEnumeration -Name UseCase -ComputerName $server

$ChildEnum = get-scsmchildenumeration -Enumeration $rootEnum -computername $server |?{$_.DisplayName -like '*DigiLeih*'}

$ChildEnum | Select Name, DisplayName, ID

$hwasset | Set-SCSMObject -Property UseCase -Value $ChildEnum -ComputerName $server

----

Result:

Name                Enum.d252c5dec3f44fcba1c38c23a7709796

DisplayName         ENUM.MDM.Projekte.DigiLeih

Id                   e8db02e7-2e8e-7140-9ccd-22ea35810fa9

---      

Ordinal is 14,5.

It is running without any error, but the field is still empty.

The Enum is nested:


We created it in an old management pack and added all new elements in this GUI.

<EnumerationTypes>

    <EnumerationValue ID="UKA_HardwareAssetUseCase" Accessibility="Public" />

</EnumerationTypes>

The other 'selfmade' enums work with set-scsmobject but they are not nested.


Hope, anybody can help.

Sarah

Best Answer

  • Simon_ZeinhoferSimon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭
    edited March 2023 Answer ✓

    @Sarah_Geihs Using a nested enumeration should make no difference to a non-nested one. In your case, the first option should be:

    Set-SCSMObject -SMObject $hwasset -Property UseCase -Value "ENUM.MDM.Projekte.DigiLeih"
    

    with quotation marks around the property value.

    But still, for enumerations there are some different ways to accomplish that.

    1) Use the displayname of the value, like you did - To be sure, use quotation marks around the Name. This works in most circumstances, still not my preference.

    2) You can use the enumeration itself, like you did in option 2. When using any get-scsm... functions in conjunction with the -name parameter, always be sure to add a $ after the name, especially for ootb ones. E.g. if you write

    Get-scsmclass -name 'System.WorkItem.Incident
    

    the result is different from

    Get-scsmclass -name 'System.WorkItem.Incident$
    


    as you receive two classes in the first example. The first example seems to be like a contains, as the 2nd one is an equals.

    Back to the get-scsmenumeration... / get-scsmchildenumeration. I recommend using it that way:

    $childEnum = Get-scsmchildenumeration -Enumeration $rootEnum -depth recursive | ? {....}
    

    The -recursive parameter lets you receive all nested enumerations, even from a top root enum as well, no matter how nested it is. So when you receive the enumeration you need, you can use it with

    Set-scsmobject -smobject $hwasset -property UseCase -value $childEnum -passthru
    

    With UR4 from SCSM 2019 we encountered some issues with smlets, especially when we use the set-scsmobject with an enumeration object or the displayname of it, be it with -property -value or inside a hashtable which contains the property and value.

    Let's say we have two enumerations, both inside the List Hardware Asset Type List, Value 1 is "NBWSCAD" and value 2 is "WSCAD". Whenever we use the enumeration object or displayname of the "WSCAD", the enumeration is set to "NBWSCAD". We encountered the same with Incident Classification Enums "LAN" and "WLAN". So it seems like when we have 2 enumerations, where both end with the enum displayname which we provided, there is a 50:50 chance the wrong one is selected and passed into the property value. I guess it has something to do with the IDs and/or ordinal numbers of the list values.

    So there is a third option, which has worked in 100 % of our cases.

    3) Let's say you receive the enumeration with the

    $childEnum = Get-scsmchildenumeration -Enumeration $rootEnum -depth recursive | ? {....}
    

    function, then you should see the properties Name, DisplayName and Id. For non-ootb enumerations, the name is always something like Enum.* - And this Enum.* is the value which you can pass to the property value, so in your case it should be either

    Set-scsmobject -smobject $hwAsset -property UseCase -Value "Enum.d252c5dec3f44fcba1c38c23a7709796"
    

    or imo the better way

    Set-scsmobject -smobject $hwAsset -property UseCase -Value $childEnum.Name
    

    Especially if you wanna set multiple properties at once, creating a hashtable is really useful, like

    $newHWProperties = @{
        UseCase = $childEnum.Name;
        Property1 = "Value1"
        .
        .
        .
    } 
    

    And then using it via

    Set-scsmobject -smobject $hwAsset -propertyhashtable $newHWProperties
    

    For receiving a certain enumeration via get-scsmenumeration, I ALWAYS use the ID, and not get-scsmchildenumeration... Especially what you did in your example with

    ...| ?{$_.DisplayName -like....}
    

    might leed to multiple results and especially in bigger scripts, leads to errors.

    If you wanna check IDs of Classes, Enums etc. I recommend using the Entity Explorer (Link is inside one of the answers):

    It is a really useful tool, which makes working with Classes and Enumerations a lot easier.

    One last tip:

    When setting enumeration values inside a Class Object, always be sure to use the correct Property name, as the List name is not always the name of the property inside the object which uses it. Best example is the CatalogItemModel. The list is called CatalogItemModel and the property inside the HW Asset Class is called ModelEnum. So have you tested the field value inside the portal, or inside the scsm console? Because in the portal, maybe you have the wrong value inside the "PropertyName" and therefor it is showing nothing. I had the same issue some time ago, as I named the Enumeration Name and Property Name differently.

    I hope this was helpful :)

Answers

  • Simon_ZeinhoferSimon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭
    edited March 2023 Answer ✓

    @Sarah_Geihs Using a nested enumeration should make no difference to a non-nested one. In your case, the first option should be:

    Set-SCSMObject -SMObject $hwasset -Property UseCase -Value "ENUM.MDM.Projekte.DigiLeih"
    

    with quotation marks around the property value.

    But still, for enumerations there are some different ways to accomplish that.

    1) Use the displayname of the value, like you did - To be sure, use quotation marks around the Name. This works in most circumstances, still not my preference.

    2) You can use the enumeration itself, like you did in option 2. When using any get-scsm... functions in conjunction with the -name parameter, always be sure to add a $ after the name, especially for ootb ones. E.g. if you write

    Get-scsmclass -name 'System.WorkItem.Incident
    

    the result is different from

    Get-scsmclass -name 'System.WorkItem.Incident$
    


    as you receive two classes in the first example. The first example seems to be like a contains, as the 2nd one is an equals.

    Back to the get-scsmenumeration... / get-scsmchildenumeration. I recommend using it that way:

    $childEnum = Get-scsmchildenumeration -Enumeration $rootEnum -depth recursive | ? {....}
    

    The -recursive parameter lets you receive all nested enumerations, even from a top root enum as well, no matter how nested it is. So when you receive the enumeration you need, you can use it with

    Set-scsmobject -smobject $hwasset -property UseCase -value $childEnum -passthru
    

    With UR4 from SCSM 2019 we encountered some issues with smlets, especially when we use the set-scsmobject with an enumeration object or the displayname of it, be it with -property -value or inside a hashtable which contains the property and value.

    Let's say we have two enumerations, both inside the List Hardware Asset Type List, Value 1 is "NBWSCAD" and value 2 is "WSCAD". Whenever we use the enumeration object or displayname of the "WSCAD", the enumeration is set to "NBWSCAD". We encountered the same with Incident Classification Enums "LAN" and "WLAN". So it seems like when we have 2 enumerations, where both end with the enum displayname which we provided, there is a 50:50 chance the wrong one is selected and passed into the property value. I guess it has something to do with the IDs and/or ordinal numbers of the list values.

    So there is a third option, which has worked in 100 % of our cases.

    3) Let's say you receive the enumeration with the

    $childEnum = Get-scsmchildenumeration -Enumeration $rootEnum -depth recursive | ? {....}
    

    function, then you should see the properties Name, DisplayName and Id. For non-ootb enumerations, the name is always something like Enum.* - And this Enum.* is the value which you can pass to the property value, so in your case it should be either

    Set-scsmobject -smobject $hwAsset -property UseCase -Value "Enum.d252c5dec3f44fcba1c38c23a7709796"
    

    or imo the better way

    Set-scsmobject -smobject $hwAsset -property UseCase -Value $childEnum.Name
    

    Especially if you wanna set multiple properties at once, creating a hashtable is really useful, like

    $newHWProperties = @{
        UseCase = $childEnum.Name;
        Property1 = "Value1"
        .
        .
        .
    } 
    

    And then using it via

    Set-scsmobject -smobject $hwAsset -propertyhashtable $newHWProperties
    

    For receiving a certain enumeration via get-scsmenumeration, I ALWAYS use the ID, and not get-scsmchildenumeration... Especially what you did in your example with

    ...| ?{$_.DisplayName -like....}
    

    might leed to multiple results and especially in bigger scripts, leads to errors.

    If you wanna check IDs of Classes, Enums etc. I recommend using the Entity Explorer (Link is inside one of the answers):

    It is a really useful tool, which makes working with Classes and Enumerations a lot easier.

    One last tip:

    When setting enumeration values inside a Class Object, always be sure to use the correct Property name, as the List name is not always the name of the property inside the object which uses it. Best example is the CatalogItemModel. The list is called CatalogItemModel and the property inside the HW Asset Class is called ModelEnum. So have you tested the field value inside the portal, or inside the scsm console? Because in the portal, maybe you have the wrong value inside the "PropertyName" and therefor it is showing nothing. I had the same issue some time ago, as I named the Enumeration Name and Property Name differently.

    I hope this was helpful :)

Sign In or Register to comment.