Jump to content

Rob Gething

Hornbill Users
  • Posts

    37
  • Joined

  • Last visited

Posts posted by Rob Gething

  1. I'm trying to create a Power Automate flow that'll receive a JSON array via a HTTP request, create a CSV table from the array and create a file in OneDrive.

    I want to take the file that's been created in OneDrive and upload it to the session folder it DAV and then attach the uploaded file to a request.

    When I try to do a HTTP PUT request, I get an error with a 403 status code saying "You do not have a sufficient priv level to access this resource".

    I am using https://mdh-p01-api.hornbill.com/iposervicedesk/dav/session/2023-09-08T08_42_12.9974088Z.csv as the URL and using an API key that has been generated under the system admin account, so access shouldn't be an issue.

    This was originally working about 11am yesterday morning, but was uploading blank files and attaching them to the request, it has since stopped working and is failing at this step.

    If I use POST rather than PUT, a 404 HTTP status code is returned.

  2. I have the following code:

     

    function New-HBIncident {
    <#
    .Synopsis
       Script to logs a new incident in Hornbill.
    
    .DESCRIPTION
      The script logs a new incident in Hornbill.
    
    .LINK
      https://ukipo.visualstudio.com/IT%20Operations/_git/Powershell?path=/Morning_Checks
    
    .NOTES
      Version:  1.0
      Author:	Robert Gething/Mark White
      Created:	09.02.2023
      Updated:	
      History:	1.0 - Initial script release
    
    #.PARAMETER instanceName
    #MANDATORY: The name of the Instance to connect to.
    
    #.PARAMETER instanceKey
    #MANDATORY: An API key with permission on the Instance to carry out the required API calls.
    
    #.PARAMETER assetIds
    #A comma-seperated string of asset IDs to attach to the new request, for example: 1,12,36
    
    #.PARAMETER bpmName
    #The name of a BPM to override the Service BPM or Default BPM.
    
    #.PARAMETER catalogName
    #The title of the catalog to raise thew request against
    
    #.PARAMETER categoryId
    #The ID of the request category
    
    #.PARAMETER categoryName
    #The fullname of the request category
    
    #.PARAMETER customerId
    #The ID of the request customer
    
    #.PARAMETER customerType
    #The Type of the request customer (0 for Users, 1 for contacts)
    
    #.PARAMETER description
    #The request description
    
    #.PARAMETER ownerId
    #The ID of the request owner
    
    #.PARAMETER priorityName
    #The name of the request Priority
    
    #.PARAMETER resolutionDetails
    #The resolution description
    
    #.PARAMETER serviceName
    #The name of the service to raise the request against
    
    #.PARAMETER siteName
    #The name of the request site
    
    #.PARAMETER sourceId
    #The ID of the request source
    
    #.PARAMETER sourceType
    #The Type of request source
    
    #.PARAMETER status
    #The status of the new request (defaults to status.open)
    
    #.PARAMETER summary
    #The request summary
    
    #.PARAMETER teamId
    #The ID of the team that the request should be assigned to
    
    #Requires -Module @{ModuleVersion = '1.1.0'; ModuleName = 'HornbillAPI'}
    #Requires -Module @{ModuleVersion = '1.1.1'; ModuleName = 'HornbillHelpers'}
    #>
    	# Define output stream type
    	[OutputType([object])]
    	# Define runbook input params
    	Param
    	(
    		
    		# API Params
    		[string]$assetIds,
    		[string]$bpmName,
    		[string]$catalogName,
    		[string]$categoryId,
    		[string]$categoryName,
    		[string]$customerId,
    		[string]$customerType,
    		[string]$description,
    		[string]$ownerId,
    		[string]$priorityName,
    		[string]$resolutionDetails,
    		[string]$serviceName,
    		[string]$siteName,
    		[string]$sourceId,
    		[string]$sourceType,
    		[string]$status,
    		[string]$summary,
    		[string]$teamId
    	)
    	
    	# Get service ID from Name
    	$serviceId = ""
    	if ($serviceName -and $serviceName -ne "")
    	{
    		$serviceObj = Get-HB-ServiceID $serviceName
    		if ($serviceObj.ServiceID -gt 0)
    		{
    			$serviceId = $serviceObj.ServiceID
    		}
    	}
    	
    	# Get Priority ID from Name
    	$priorityId = ""
    	if ($priorityName -and $priorityName -ne "")
    	{
    		$priorityObj = Get-HB-PriorityID $priorityName
    		if ($priorityObj.PriorityID -gt 0)
    		{
    			$priorityId = $priorityObj.PriorityID
    		}
    	}
    	
    	# Get Catalog ItemID from Name
    	$catItemId = ""
    	if ($catalogName -and $catalogName -ne "")
    	{
    		$catalogObj = Get-HB-CatalogID $catalogName $serviceName "Incident"
    		if ($catalogObj.CatalogID -gt 0)
    		{
    			$catItemId = $catalogObj.CatalogID
    		}
    	}
    	
    	# Get SiteID from Name
    	$siteId = ""
    	if ($siteName -and $siteName -ne "")
    	{
    		$siteObj = Get-HB-SiteID $siteName
    		$siteId = $siteObj.SiteID
    	}
    	
    	# Populate status if null
    	if (-not $status -or $status -eq "")
    	{
    		$status = "status.open"
    	}
    	
    	Add-HB-Param "summary" $summary $false
    	Add-HB-Param "description" $description $false
    	Add-HB-Param "customerId" $customerId $false
    	Add-HB-Param "customerType" $customerType $false
    	Add-HB-Param "ownerId" $ownerId $false
    	Add-HB-Param "teamId" $teamId $false
    	Add-HB-Param "status" $status $false
    	Add-HB-Param "priorityId" $priorityId $false
    	Add-HB-Param "categoryId" $categoryId $false
    	Add-HB-Param "categoryName" $categoryName $false
    	Add-HB-Param "sourceType" $sourceType $false
    	Add-HB-Param "sourceId" $sourceId $false
    	
    	# Process Assets
    	if ($assetIds)
    	{
    		$arrAssets = $assetIds.replace(' ', '').split(',')
    		foreach ($asset in $arrAssets)
    		{
    			Add-HB-Param "assetId" $asset $false
    		}
    	}
    	
    	Add-HB-Param "serviceId" $serviceId $false
    	Add-HB-Param "resolutionDetails" $resolutionDetails $false
    	Add-HB-Param "siteId" $siteId $false
    	Add-HB-Param "siteName" $siteName $false
    	Add-HB-Param "catalogId" $catItemId $false
    	Add-HB-Param "catalogName" $catalogName $false
    	Add-HB-Param "bpmName" $bpmName $false
    	
    	# Invoke XMLMC call, output returned as PSObject
    	$xmlmcOutput = Invoke-HB-XMLMC "apps/com.hornbill.servicemanager/Incidents" "logIncident"
    	
    	$exceptionName = ""
    	$exceptionSummary = ""
    	# Read output status
    	if ($xmlmcOutput.status -eq "ok")
    	{
    		if ($xmlmcOutput.params.requestId -and $xmlmcOutput.params.requestId -ne "")
    		{
    			$requestRef = $xmlmcOutput.params.requestId
    			$requestWarnings = $xmlmcOutput.params.warnings
    		}
    		if ($xmlmcOutput.params.exceptionName -and $xmlmcOutput.params.exceptionName -ne "")
    		{
    			$exceptionName = $xmlmcOutput.params.exceptionName
    			$exceptionSummary = $xmlmcOutput.params.exceptionDescription
    		}
    	}
    	# Build resultObject to write to output
    	$resultObject = New-Object PSObject -Property @{
    		Status		     = $xmlmcOutput.status
    		Error		     = $xmlmcOutput.error
    		RequestRef	     = $requestRef
    		Warnings		 = $requestWarnings
    		ExceptionName    = $exceptionName
    		ExceptionSummary = $exceptionSummary
    	}
    	
    	if ($resultObject.Status -ne "ok")
    	{
    		Write-Error $resultObject
    	}
    	else
    	{
    		if ($exceptionName -ne "")
    		{
    			Write-Warning $resultObject
    		}
    		else
    		{
    			Write-Output $resultObject
    		}
    	}
    }
    
    #Connect to Hornbill API
    Write-Verbose "Connecting to Hornbill..."
    Set-HB-Instance -Instance $instance -Key $key
    Set-HB-Proxy -ProxyAddress $proxy
    
    $serviceName = "2. Request Something"
    $catalogName = "Raise a request with IT support"
    $priorityName = "Priority 3"
    $NewHBIncidentParams = @{
    	dummary = "Test"
    	description = "Test"
    	customerId = "HORNL"
    	customerType = 0
    	teamId  = "IPO/IT/OPS/APPSL2/"
    	status  = "status.open"
    	priorityId = 18
    	sourceType = "Automated Morning Checks"
        serviceId = "555"
    	siteId  = 1
    	siteName = "Concept House, Cardiff Road"
    }
    $NewIncident = New-HBIncident @NewHBIncidentParams

    When I try to add:

    bpmName = "morning-checks-automation"

    I get:

    {"logRequestBpmFailed":"There was an error in the starting the BPM process for this request. Details: 
                       defaultProcessNotSet - undefined"}

    The workflow is set and the service is available:

    image.thumb.png.102c6337728b48551294bd424d0ce06b.png

     

    When I try to use:
     

    # Define output stream type
        [OutputType([object])]
    
        # Define runbook input params
        Param
        (
            # API Params
            [string] $requestId = "IN00220363",
            [string] $defaultBpm = 'morning-checks-automation'
            )
    
        Set-HB-Instance -Instance $instance -Key $key
        Set-HB-Proxy -ProxyAddress $proxy
    
        # Add XMLMC params
        Add-HB-Param "requestId" $requestId $false
        Add-HB-Param "defaultBpm" $defaultBpm $false
    
       # Invoke XMLMC call, output returned as PSObject
       $xmlmcOutput = Invoke-HB-XMLMC "Requests" "logRequestBPM"
       $exceptionName = "" 
       $exceptionSummary = ""
       
        # Read output status
        if($xmlmcOutput.params.bpmProcessId -and $xmlmcOutput.params.bpmProcessId -ne ""){
                $bpmProcessId = $xmlmcOutput.params.bpmProcessId
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            if($xmlmcOutput.params.exceptionName -and $xmlmcOutput.params.exceptionName -ne ""){
                $exceptionName = $xmlmcOutput.params.exceptionName
                $exceptionSummary = $xmlmcOutput.params.exceptionDescription
            }
        
        # Build resultObject to write to output
        $resultObject = New-Object PSObject -Property @{
            Status = $xmlmcOutput.status
            Error = $xmlmcOutput.error
            ExceptionName = $exceptionName
            ExceptionSummary = $exceptionSummary
            bpmProcessId = $bpmProcessId
            }
    
        if($resultObject.Status -ne "ok" -or $exceptionName -ne ""){
            Write-Error $resultObject
        } else {
            Write-Output $resultObject
           }

    I get:

    @{Status=fail; Error=The service 
    specified is not available: Requests; bpmProcessId=; ExceptionName=; ExceptionSummary=}

    I presume this is because the serviceId is not being parsed, but when I try to parse a serviceId i.e. 551, the service still fails to link to the request.

    Where am I going wrong here?

  3. Hi,

    I am looking to take ITOM to our Technical Design Authority, seeking approval for use on our estate, however a couple of concerns have been raised, which I am hoping that you can address:

    • User and group management is quite a privilege, what’s stopping a bad actor within Hornbill, or one that’s compromised Hornbill systems from creating themselves accounts etc?
    • How do we know the wrong accounts won’t accidentally be deleted or amended?

    Thanks.

  4. @Victor,

    The use case here is that I am trying to use Power Automate flow to parse responses from MS Forms to Hornbill via the API to log a service request.

    I'm using a Parse JSON node with the following body:

    {
      "form_id""RGETHMSFormsTest",
      "question""Test 1",
      "question_id""RGETHMSFormsTest1",
      "answer""CCC",
      "answer_value""CCC",
      "field_type""text",
      "entity_type""request",
      "hbfield": {
        "question""Test 1",
        "field": {
          "id""RGETHMSFormsTest1",
          "defLabel""Test 1",
          "transLabel""x",
          "binding""global.RGETHMSFormsTest.RGETHMSFormsTest1",
          "noInvisibleValue"false,
          "design": {
            "isVisible"true,
            "isMandatory"false,
            "isReadOnly"false,
            "showIfEmpty"false,
            "extraClass"" "
          },
          "control": {
            "type""text"
          },
          "uid""RGETHMSFormsTest-1-1"
        },
        "value""CCC"
      }
    }
     
    Schema:
     
    {
      "type""object",
      "properties": {
        "form_id": {
          "type""string"
        },
        "question": {
          "type""string"
        },
        "question_id": {
          "type""string"
        },
        "answer": {
          "type""string"
        },
        "answer_value": {
          "type""string"
        },
        "field_type": {
          "type""string"
        },
        "entity_type": {
          "type""string"
        },
        "hbfield": {
          "type""object",
          "properties": {
            "question": {
              "type""string"
            },
            "field": {
              "type""object",
              "properties": {
                "id": {
                  "type""string"
                },
                "defLabel": {
                  "type""string"
                },
                "transLabel": {
                  "type""string"
                },
                "binding": {
                  "type""string"
                },
                "noInvisibleValue": {
                  "type""boolean"
                },
                "design": {
                  "type""object",
                  "properties": {
                    "isVisible": {
                      "type""boolean"
                    },
                    "isMandatory": {
                      "type""boolean"
                    },
                    "isReadOnly": {
                      "type""boolean"
                    },
                    "showIfEmpty": {
                      "type""boolean"
                    },
                    "extraClass": {
                      "type""string"
                    }
                  }
                },
                "control": {
                  "type""object",
                  "properties": {
                    "type": {
                      "type""string"
                    }
                  }
                },
                "uid": {
                  "type""string"
                }
              }
            },
            "value": {
              "type""string"
            }
          }
        }
      }
    }
     
    HTTP node body:
     
    {
      "methodCall": {
        "params": {
          "requestType""Service Request",
          "questions""{\"form_id\":\"RGETHMSFormsTest\",\"question\":\"Test 1\",\"question_id\":\"RGETHMSFormsTest1\",\"answer\":\"CCC\",\"answer_value\":\"CCC\",\"field_type\":\"text\",\"entity_type\":\"request\",\"hbfield\":{\"question\":\"Test 1\",\"field\":{\"id\":\"RGETHMSFormsTest1\",\"defLabel\":\"Test 1\",\"transLabel\":\"x\",\"binding\":\"global.RGETHMSFormsTest.RGETHMSFormsTest1\",\"noInvisibleValue\":false,\"design\":{\"isVisible\":true,\"isMandatory\":false,\"isReadOnly\":false,\"showIfEmpty\":false,\"extraClass\":\" \"},\"control\":{\"type\":\"text\"},\"uid\":\"RGETHMSFormsTest-1-1\"},\"value\":\"CCC\"}}"
        },
        "@service""apps/com.hornbill.servicemanager/Requests",
        "@method""logRequest"
      }
    }
     
    Result:

    <?xml version="1.0" encoding="utf-8" ?>
    <methodCallResult status="ok">
        <params>
            <requestId>SR00173033</requestId>
            <exceptionName>addQuestionFailure</exceptionName>
        </params>
        <flowCodeDebugState>
            <executionId>077bf616-9339-438f-97ce-caef91347e64</executionId>
        </flowCodeDebugState>
    </methodCallResult>

    A call logs, but no questions are on the call.
     

  5. I have followed the instructions in: TextAnywhere - Hornbill, but when I try to setup a BPM workflow, I get the following error during execution:

    Status : Failed

    Last Updated On : 07-07-2022 17:03:16

    iBridge Method: /TextAnywhere/Send SMS.m Error: Http::post: Failed to make HTTP 'POST' request to server

    I have confirmed that the client ID and client password in the keysafe are correct, the node is configured as follows:

    image.thumb.png.4cc84648aa218ef451de14e660829b74.png

  6. I wrote a PowerShell script to change An Asset Class from mobileDevice to computer using entityUpdateRecord:

                       

    Add-HB-Param        "application" "com.hornbill.servicemanager"
                        Add-HB-Param        "entity" "Asset"
                        Add-HB-Param        "returnModifiedData" "true"
                        Open-HB-Element     "primaryEntityData"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_pk_asset_id" "506"
                        Add-HB-Param        "h_class" "computer"
                        Add-HB-Param        "h_asset_urn" ("urn:sys:entity:com.hornbill.servicemanager:Asset:")
                        Close-HB-Element    "record"
                        Close-HB-Element    "primaryEntityData"
                        $UpdateAsset = Invoke-HB-XMLMC "data" "entityUpdateRecord"
                        if($UpdateAsset.status -ne 'ok') {
                        Write-Output $UpdateAsset.Error -ErrorAction Stop
                        }
                        else{
                        Write-Output "Asset Primary Record Updated"
                        Add-HB-Param        "application" "com.hornbill.servicemanager"
                        Add-HB-Param        "entity" "Asset"
                        Add-HB-Param        "returnModifiedData" "true"
                        Open-HB-Element     "primaryEntityData"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_pk_asset_id" "506"
                        Close-HB-Element    "record"
                        Close-HB-Element    "primaryEntityData"
                        Open-HB-Element     "relatedEntityData"
                        Add-HB-Param        "relationshipName" "AssetClass"
                        Add-HB-Param        "entityAction" "update"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_type" "3"
                        Close-HB-Element    "record"
                        Close-HB-Element    "relatedEntityData"
                        $UpdateAssetRelated = Invoke-HB-XMLMC "data" "entityUpdateRecord"
                        }
                        if($UpdateAssetRelated.status -eq 'ok') {
                        Write-Output "Asset Related Record Updated"
                        }
                        else {
                        Write-Output $UpdateAssetRelated.Error
                        }

    If I run it against asset ID 506, I get:

    Asset Primary Record Updated
    There are no values to update

    You can see from the attached image that the record does actually change the class to computer an the type to physical as expected:

    If I use any other asset ID, I get:

    A database or query error occurred while updating record(s)

    Any idea what's special about 506 and why it works for that record. but will not work for any others?

    Capture.PNG

  7. @AndyHill,

    Does this help you at all?

    <#PSScriptInfo
    .VERSION 1.0.0
    .AUTHOR robert.gething@ipo.gov.uk
    .COMPANYNAME UK IPO
    .TAGS hornbill powershell intune azure automation workflow runbook
    .RELEASENOTES
    Initial Release
    .DESCRIPTION 
     Azure Automation Runbook to retrieve mobile assets from Intune, and import them into your Hornbill instance CMDB. 
    #>
     
    #Requires -Module @{ModuleVersion = '1.1.0'; ModuleName = 'HornbillAPI'}
    #Requires -Module @{ModuleVersion = '1.1.1'; ModuleName = 'HornbillHelpers'}
     
    #Retrieve Microsoft Intune tenant information
    $intuneAutomationCredential = Get-AutomationPSCredential -Name IntuneAutomation
    $intuneAutomationAppId = Get-AutomationVariable -Name AutomationVar
    $tenant = Get-AutomationVariable -Name AzureADTenantId
    $Resource = "https://graph.microsoft.com/beta/deviceManagement/managedDevices"
     
    # Define Hornbill Params
    $AssetClass = "mobileDevice" # Asset Class for Mobile Devices in your Hornbill instance
    $AssetType = "11" # Primary Key for the "Smart Phone" asset type in your Hornbill instance
    $AssetEntity = "AssetsMobileDevice" # Entity name of the Hornbill entity used to check for existing assets 
    $AssetUniqueColumn = "h_serial_number" # Column in the above entity used to check for existing assets
     
    #Import Azure AD PowerShell for Graph (GA)
    $AadModule = Import-Module -Name AzureAD -ErrorAction Stop -PassThru
     
    #Import Hornbill Modules
    Import-Module -Name HornbillAPI -ErrorAction Stop -WarningAction silentlyContinue
    Import-Module -Name HornbillHelpers -ErrorAction Stop -WarningAction silentlyContinue
     
    # Create Hornbill instance details
    Set-HB-Instance -Instance (Get-AutomationVariable -Name InstanceID) -Key (Get-AutomationVariable -Name APIKey)
     
    #Authenticate with the Graph API REST interface
    $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
    $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"
    [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null
    [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null
    $redirectUri = "urn:ietf:wg:oauth:2.0:oob"
    $resourceAppIdURI = "https://graph.microsoft.com"
    $authority = "https://login.microsoftonline.com/$tenant"
     
    try {
        $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority 
        # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx
        # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession
        $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto"
        $userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList ($intuneAutomationCredential.Username, "OptionalDisplayableId")   
        $userCredentials = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential -ArgumentList $intuneAutomationCredential.Username, $intuneAutomationCredential.Password
        $authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext$resourceAppIdURI$intuneAutomationAppId$userCredentials);
     
        if ($authResult.Result.AccessToken) {
            $authHeader = @{
                'Content-Type'  = 'application/json'
                'Authorization' = "Bearer " + $authResult.Result.AccessToken
                'ExpiresOn'     = $authResult.Result.ExpiresOn
            }
        }
        elseif ($authResult.Exception) {
            throw "An error occured getting access token: $($authResult.Exception.InnerException)"
        }
    }
    catch { 
        throw $_.Exception.Message 
    }
    $LastLoop = $false
    $AssetsProcessed = @{
        "created" = 0
        "primaryupdated" = 0
        "relatedupdated" = 0
        "found" = 0
        "totalupdated" = 0
    }
    while($LastLoop -eq $false -and $Resource -ne "") {
        Write-Output -InputObject ("Retrieving devices from: " + $Resource)
        $ManagedDevices = Invoke-RestMethod -Uri $Resource -Method Get -Headers $authHeader
     
        $DeviceCount = 0
        if($ManagedDevices.PSobject.Properties.name -match "@odata.count") {
            $DeviceCount = $ManagedDevices."@odata.count"
        }
        $Resource = ""
        if($ManagedDevices.PSobject.Properties.name -match "@odata.nextLink") {
            $Resource = $ManagedDevices."@odata.nextLink"
        }
     
        if($DeviceCount -eq 0) {
            $LastLoop = $true
        } else {
            $DevicesArr = $ManagedDevices.Value
            if($null -ne $DevicesArr) {
                foreach($Device in $DevicesArr){
                    $AssetsProcessed.found++
                    #Set Date/Time
                    $CurrDateTime = Get-Date -format "yyyy/MM/dd HH:mm:ss"
                    #Does asset exist?
                    $AssetIDCheck = Get-HB-AssetID $Device.serialNumber $AssetEntity $AssetUniqueColumn
                    if$null -ne $AssetIDCheck.AssetID) {
                        Write-Output -InputObject ("Asset already exists, updating: " + $AssetIDCheck.AssetID)
                        $UpdatedPrimary = $false
                        $UpdatedRelated = $false
                        #Asset Exists - Update Primary Entity Data First
                        Add-HB-Param        "application" "com.hornbill.servicemanager"
                        Add-HB-Param        "entity" "Asset"
                        Add-HB-Param        "returnModifiedData" "true"
                        Open-HB-Element     "primaryEntityData"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_pk_asset_id" $AssetIDCheck.AssetID
                        Add-HB-Param        "h_class" $AssetClass
                        Add-HB-Param        "h_asset_urn" ("urn:sys:entity:com.hornbill.servicemanager:Asset:"+$AssetIDCheck.AssetID)
                        if($null -ne $Device.userDisplayName -and $null -ne $Device.userPrincipalName) {
                            $OwnerURN = "urn:sys:0:" + $Device.userDisplayName + ":" + $Device.userPrincipalName
                            Add-HB-Param        "h_owned_by" $OwnerURN
                            Add-HB-Param        "h_owned_by_name" $Device.userDisplayName
                        }
                        Add-HB-Param        "h_name" $Device.deviceName
                        Add-HB-Param        "h_description" $Device.managedDeviceName
                        Close-HB-Element    "record"
                        Close-HB-Element    "primaryEntityData"
                        $UpdateAsset = Invoke-HB-XMLMC "data" "entityUpdateRecord"
     
                        if($UpdateAsset.status -eq 'ok' -and $UpdateAsset.params.primaryEntityData.PSobject.Properties.name -match "record") {
                            $UpdatedPrimary = $true
                            $AssetsProcessed.primaryupdated++
                            Write-Output -InputObject ("Asset Primary Record Updated: " + $AssetIDCheck.AssetID)
                        } else {
                            $ErrorMess = $UpdateAsset.error
                            if($UpdateAsset.params.primaryEntityData.PSobject.Properties.name -notmatch "record") {
                                $ErrorMess = "There are no values to update" 
                            }
                            Write-Warning ("Error Updating Primary Asset Record " + $AssetIDCheck.AssetID + ": " + $ErrorMess)
                        }
     
                        # Now update related record information
                        Add-HB-Param        "application" "com.hornbill.servicemanager"
                        Add-HB-Param        "entity" "Asset"
                        Add-HB-Param        "returnModifiedData" "true"
                        Open-HB-Element     "primaryEntityData"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_pk_asset_id" $AssetIDCheck.AssetID
                        Close-HB-Element    "record"
                        Close-HB-Element    "primaryEntityData"
                        Open-HB-Element     "relatedEntityData"
                        Add-HB-Param        "relationshipName" "AssetClass"
                        Add-HB-Param        "entityAction" "update"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_type" $AssetType
                        Add-HB-Param        "h_capacity" $Device.totalStorageSpaceInBytes
                        Add-HB-Param        "h_description" $Device.managedDeviceName
                        Add-HB-Param        "h_imei_number" $Device.imei
                        Add-HB-Param        "h_mac_address" $Device.wiFiMacAddress
                        Add-HB-Param        "h_manufacturer" $Device.manufacturer
                        Add-HB-Param        "h_model" $Device.model
                        Add-HB-Param        "h_name" $Device.deviceName
                        Add-HB-Param        "h_os_version" ($Device.operatingSystem + " " + $Device.osVersion)
                        Add-HB-Param        "h_phone_number" $Device.phoneNumber
                        Add-HB-Param        "h_serial_number" $Device.serialNumber
                        Close-HB-Element    "record"
                        Close-HB-Element    "relatedEntityData"
                        $UpdateAssetRelated = Invoke-HB-XMLMC "data" "entityUpdateRecord"
                        if($UpdateAssetRelated.status -eq 'ok') {
                            $UpdatedRelated = $true
                            $AssetsProcessed.relatedupdated++
                            Write-Output -InputObject ("Asset Related Record Updated: " + $AssetIDCheck.AssetID)
                        } else {
                            Write-Warning ("Error Updating Related Asset Record " + $AssetIDCheck.AssetID + ": " + $UpdateAssetRelated.error)
                        }
     
                        if($UpdatedPrimary -eq $true -or $UpdatedRelated -eq $true) {
                            $AssetsProcessed.totalupdated++
                            #Update Last Udated fields
                            Add-HB-Param        "application" "com.hornbill.servicemanager"
                            Add-HB-Param        "entity" "Asset"
                            Open-HB-Element     "primaryEntityData"
                            Open-HB-Element     "record"
                            Add-HB-Param        "h_pk_asset_id" $AssetIDCheck.AssetID
                            Add-HB-Param        "h_last_updated" $CurrDateTime
                            Add-HB-Param        "h_last_updated_by" "Azure Intune Import"
                            Close-HB-Element    "record"
                            Close-HB-Element    "primaryEntityData"
                            $UpdateLastAsset = Invoke-HB-XMLMC "data" "entityUpdateRecord"
                            if($UpdateLastAsset.status -ne 'ok') {
                                Write-Warning ("Asset updated but error returned updating Last Updated values: " + $UpdateLastAsset.error)    
                            }
                        }
     
                    } else {
                        #Asset doesn't exist - Add
                        Add-HB-Param        "application" "com.hornbill.servicemanager"
                        Add-HB-Param        "entity" "Asset"
                        Add-HB-Param        "returnModifiedData" "true"
                        Open-HB-Element     "primaryEntityData"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_class" $AssetClass
                        Add-HB-Param        "h_type" $AssetType
                        Add-HB-Param        "h_last_updated" $CurrDateTime
                        Add-HB-Param        "h_last_updated_by" "Azure Intune Import"
                        if($null -ne $Device.userDisplayName -and $null -ne $Device.userPrincipalName) {
                            $OwnerURN = "urn:sys:0:" + $Device.userDisplayName + ":" + $Device.userPrincipalName
                            Add-HB-Param        "h_owned_by" $OwnerURN
                            Add-HB-Param        "h_owned_by_name" $Device.userDisplayName
                        }
                        Add-HB-Param        "h_name" $Device.deviceName
                        Add-HB-Param        "h_description" $Device.managedDeviceName
                        Close-HB-Element    "record"
                        Close-HB-Element    "primaryEntityData"
                        Open-HB-Element     "relatedEntityData"
                        Add-HB-Param        "relationshipName" "AssetClass"
                        Add-HB-Param        "entityAction" "insert"
                        Open-HB-Element     "record"
                        Add-HB-Param        "h_type" $AssetType
                        Add-HB-Param        "h_capacity" $Device.totalStorageSpaceInBytes
                        Add-HB-Param        "h_description" $Device.managedDeviceName
                        Add-HB-Param        "h_imei_number" $Device.imei
                        Add-HB-Param        "h_mac_address" $Device.wiFiMacAddress
                        Add-HB-Param        "h_manufacturer" $Device.manufacturer
                        Add-HB-Param        "h_model" $Device.model
                        Add-HB-Param        "h_name" $Device.deviceName
                        Add-HB-Param        "h_os_version" ($Device.operatingSystem + " " + $Device.osVersion)
                        Add-HB-Param        "h_phone_number" $Device.phoneNumber
                        Add-HB-Param        "h_serial_number" $Device.serialNumber
                        Close-HB-Element    "record"
                        Close-HB-Element    "relatedEntityData"
                        $InsertAsset = Invoke-HB-XMLMC "data" "entityAddRecord"
                        if($InsertAsset.status -eq 'ok') {
                            $AssetsProcessed.created++
                            Write-Output -InputObject ("Asset Imported: " + $InsertAsset.params.primaryEntityData.record.h_pk_asset_id)
                            #Now update the asset with its URN
                            Add-HB-Param        "application" "com.hornbill.servicemanager"
                            Add-HB-Param        "entity" "Asset"
                            Open-HB-Element     "primaryEntityData"
                            Open-HB-Element     "record"
                            Add-HB-Param        "h_pk_asset_id" $InsertAsset.params.primaryEntityData.record.h_pk_asset_id
                            Add-HB-Param        "h_asset_urn" ("urn:sys:entity:com.hornbill.servicemanager:Asset:"+$InsertAsset.params.primaryEntityData.record.h_pk_asset_id)
                            Close-HB-Element    "record"
                            Close-HB-Element    "primaryEntityData"
                            $UpdateAsset = Invoke-HB-XMLMC "data" "entityUpdateRecord"
                            if($UpdateAsset.status -eq 'ok') {
                            } else {
                                Write-Warning ("Error Updating Asset URN: " + $UpdateAsset.error)    
                            }
     
                        } else {
                            Write-Warning ("Error Creating Asset: " + $InsertAsset.error)
                        }
                    }
                }
            }
        }
    }
    ""
    "IMPORT COMPLETE"
    Write-Output -InputObject ("Assets Found:" + $AssetsProcessed.found)
    Write-Output -InputObject ("Assets Created:" + $AssetsProcessed.created)
    Write-Output -InputObject ("Assets Updated:" + $AssetsProcessed.created)
    Write-Output -InputObject ("* Primary Record Updated:" + $AssetsProcessed.primaryupdated)
    Write-Output -InputObject ("* Related Record Updated:" + $AssetsProcessed.relatedupdated)
  8. @Steve G,

    I have created an Automation account and an app registration.

    I have added three variables:

    • APIKey
    • AutomationVar
    • InstanceID

    I have populated these with the relevant info and set encrypted to "No".

    All relevant modules are imported - I had issues where the AzureAD module was not detected, I had to add the PowerShellGet module to resolve this.

    I have created an entry under Shared Resources >> Credentials called IntuneAutomation and populated this with my full UPN and password for the global admin account that I use to access Intune and Azure.

    My app has the attached API permissions,  supported account types = Single Tenant. and I've added the redirect URI: urn:ietf:wg:oauth:2.0:oob.

    I am getting the following error and would like to uderstand what I am missing:

    Failed to retrieve auth token
    Retrieving devices from: https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$top=100
    The remote server returned an error: (401) Unauthorized.
    

    Capture.PNG

  9. @Victor,

    When I change the ServiceID to 1 and CatagoryID to 1, which are valid IDs:

    {
      "methodCall": {
        "@service""apps/com.hornbill.servicemanager",
        "@method""chatbotLogRequest",
        "params": {
          "userId""robert.gething@6m0jtc.onmicrosoft.com",
          "requestType""Incident",
          "summary""Software",
          "description""Test.",
          "serviceId"1,
          "catalogId"1
        }
      }
    }
     
    I get:
     
    <?xml version="1.0" encoding="utf-8" ?>
    <methodCallResult status="ok">
        <params>
            <outcome>failure</outcome>
            <error>Failed to log request: EspMethodCall::setParam: invalid value specified for &quot;bpmName&quot;</error>
        </params>
        <flowCodeDebugState>
            <executionId>de85ba5b-6c7b-4983-a440-9e73f7ddff4e</executionId>
        </flowCodeDebugState>
    </methodCallResult>

     
    If I set the ServiceID to 0 and CatagoryID to 0, I get:
     
    <?xml version="1.0" encoding="utf-8" ?>
    <methodCallResult status="ok">
        <params>
            <outcome>success</outcome>
            <requestRef>IN00001306</requestRef>
        </params>
        <flowCodeDebugState>
            <executionId>9a0fcd8d-912f-4c16-ae13-d56c2174f184</executionId>
        </flowCodeDebugState>
    </methodCallResult>
  10. @Steve Giller

    {
      "methodCall": {
        "@service""apps/com.hornbill.servicemanager",
        "@method""chatbotLogRequest",
        "params": {
          "userId""robert.gething@6m0jtc.onmicrosoft.com",
          "requestType""Incident",
          "summary""Software",
          "description""Test",
          "serviceId"5,
          "catalogId"77
        }
      }
    }
     
    The BuildPVAPackage PS script says please provide the following:

    The ID of your Hornbill instance:
    The API key for your Teams PVA account on your Hornbill instance:

    Topic - I Need Help:
    Service ID [integer], 0 to log against no Service:
    Catalog Item ID [integer], 0 to log against no Catalog Item:

    It makes no mention of catalogName so how do I set this?

  11. I have setup a PVA according to Teams Power Virtual Agent - Hornbill, but when I trigger the "I need help" topic, it fails with:

    <?xml version="1.0" encoding="utf-8" ?>
    <methodCallResult status="ok">
        <params>
            <outcome>failure</outcome>
            <error>Failed to log request: EspMethodCall::setParam: invalid value specified for &quot;catalogName&quot;</error>
        </params>
        <flowCodeDebugState>
            <executionId>07137cc7-09f5-4af7-9dc1-1f46b467f675</executionId>
        </flowCodeDebugState>
    </methodCallResult>

    Please advise how I can resolve.

  12. I have setup a PVA according to Teams Power Virtual Agent - Hornbill, but when I trigger the "I need help" topic, it fails with:

    [24/12/21 12:05] Hornbill Virtual Agent

    Sorry, the bot can't talk for a while. It's something the bot's owner needs to address. Error code: 2003. Conversation ID: a:1sRpdKJmBlAwDCW_UxiSZQu1EwZTezthuB0bMKqsIUFkm063EHs_yW1AOwa2TJBKWe1mruDht_-bRHbehJ7xheba3ZSqxdJDWqy3vODCetFwaHv73q-orLwBOsf-I6d40. Time (UTC): 12/24/2021 12:05:50 PM.

    Having done some investigation, the issue appears to be due to the search knowledge flow failing with the following error:

    Unable to process template language expressions in action 'Parse_JSON_-_Content' inputs at line '1' and column '2516': 'Required property 'content' expects a value but got null. Path ''.'.

    Although the HTTP step in the flow succeeds, I believe that the error is caused because the following is returned:

    <message>Uncaught TypeError: Cannot read property &apos;siteName&apos; of null</message>

    Full output below:

    <?xml version="1.0" encoding="utf-8" ?>
    <methodCallResult status="fail">
        <state>
            <code>0207</code>
            <service>apps</service>
            <operation>chatbotKnowledgeSearch</operation>
            <error>/apps/com.hornbill.servicemanager/flowcode/fc_ops/chatbotKnowledgeSearch.js(46): error X1001: Uncaught TypeError: Cannot read property &apos;siteName&apos; of null</error>
            <flowcodeError>
                <where>Execute</where>
                <filename>/apps/com.hornbill.servicemanager/flowcode/fc_ops/chatbotKnowledgeSearch.js</filename>
                <lineNumber>46</lineNumber>
                <columnPos>18</columnPos>
                <message>Uncaught TypeError: Cannot read property &apos;siteName&apos; of null</message>
                <errorCode>1001</errorCode>
            </flowcodeError>
        </state>
    </methodCallResult>
     

    Please advise how I can resolve.

  13. Recently a content pack update was released that added a “Microsoft Teams” key type to the keysafe.

    This key type allows us to use the PostToChannel method to as a non-AAD admin user.

    How I can modify this, so that the key type Microsoft Teams can be used, rather than the key type Microsoft:

    $UserDetails = Get-AzureUser $InstanceName $InstanceKey $InstanceMicrosoftKey $Request.Body.from.aadObjectId.

    $InstanceMicrosoftKey = 5 – Microsoft Key Type.

    $InstanceMicrosoftKey = 6 – Microsoft Teams Key Type.

    If I just change $InstanceMicrosoftKey from 5 to 6, I get a message in Teams saying that an error has occurred, so it’s obviously not as simple as just calling the other key type.

  14. Recently a content pack update was released that added a “Microsoft Teams” key type to the keysafe.

    This key type allows us to use the PostToChannel method to as a non-AAD admin user.

    How I can modify this, so that the key type Microsoft Teams can be used, rather than the key type Microsoft:

    $UserDetails = Get-AzureUser $InstanceName $InstanceKey $InstanceMicrosoftKey $Request.Body.from.aadObjectId.

    $InstanceMicrosoftKey = 5 – Microsoft Key Type.

    $InstanceMicrosoftKey = 6 – Microsoft Teams Key Type.

    If I just change $InstanceMicrosoftKey from 5 to 6, I get a message in Teams saying that an error has occurred, so it’s obviously not as simple as just calling the other key type.

  15. Final working code for the benefit of others:

    # Define output stream type
        [OutputType([object])]

        # Define runbook input params
        Param
        (
            # API Params
            #[Parameter (Mandatory= $true)]
            [string] $taskId
             )

        # Add XMLMC params
        Add-HB-Param "taskId" $taskId $false
        
       # Invoke XMLMC call, output returned as PSObject
       $xmlmcOutput = Invoke-HB-XMLMC "task" "taskGetInfo"
       $exceptionName = "" 
       $exceptionSummary = ""
       
        # Read output status
        if($xmlmcOutput.status -eq "ok") {
        if($xmlmcOutput.params.title -and $xmlmcOutput.params.title -ne ""){
                $title = $xmlmcOutput.params.title
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            if($xmlmcOutput.params.options -and $xmlmcOutput.params.options -ne ""){
                $options = $xmlmcOutput.params.options
                $requestWarnings = $xmlmcOutput.params.warnings
                }
                if($xmlmcOutput.params.createdOn -and $xmlmcOutput.params.createdOn -ne ""){
                $createdOn = $xmlmcOutput.params.createdOn
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            if($xmlmcOutput.params.createdBy -and $xmlmcOutput.params.createdBy -ne ""){
                $createdBy = $xmlmcOutput.params.createdBy
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            if($xmlmcOutput.params.owner -and $xmlmcOutput.params.owner -ne ""){
                $owner = $xmlmcOutput.params.owner
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            if($xmlmcOutput.params.outcomes -and $xmlmcOutput.params.outcomes -ne ""){
                $outcomes = $xmlmcOutput.params.outcomes
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            if($xmlmcOutput.params.taskAnswers -and $xmlmcOutput.params.taskAnswers -ne ""){
                $taskAnswers = $xmlmcOutput.params.taskAnswers
                $requestWarnings = $xmlmcOutput.params.warnings
            }
            }
        
        # Build resultObject to write to output
        $resultObject = New-Object PSObject -Property @{
            Status = $xmlmcOutput.status
            Error = $xmlmcOutput.error
            ExceptionName = $exceptionName
            ExceptionSummary = $exceptionSummary
            title = $title
            options = $options
            createdOn = $createdOn
            createdBy = $createdBy
            owner = $owner
            outcomes = $outcomes
            taskAnswers = $taskAnswers
            }

        if($resultObject.Status -ne "ok" -or $exceptionName -ne ""){
            Write-Error $resultObject
        } else {
           $taskAnswers[0] | Select value
           }

  16. I am posting my final working code for the benefit of others:

    # Define output stream type
        [CmdletBinding()]

        # Define runbook input params
        Param
        (
            # API Params
            [string] $application = "com.hornbill.servicemanager",
            [string] $listName,
            [string] $itemNameTranslation
            )

       $csv = Import-Csv -Path 'All applications.csv'
       foreach($row in $csv)
       {
       $name = $row.Name
       Add-HB-Param "application" $application $false
       Add-HB-Param "listName" $listName $false
       Add-HB-Param "itemNameTranslation" $itemNameTranslation $false
       Add-HB-Param "itemValue" $name $false
       Add-HB-Param "defaultItemName" $name $false
       Invoke-HB-XMLMC "data" "listAddItem"
       }

    • Like 1
×
×
  • Create New...