---
title: "Search for assets with ScriptRunner"
canonical: "https://support.appfire.com/space/AIP/10256758/Search%20for%20assets%20with%20ScriptRunner"
format: markdown
---
> Macro (aura-html)

This example retrieves attribute values of assets based on a custom field value in Jira. It assumes you've already obtained the custom field value using a ScriptRunner.

## Example

- Three assets are selected in a custom field, and the custom field's value contains leading and trailing commas (",187,189,208,").
- For each asset ID, the script calls the Jira search API to get the asset object and retrieves the specified attribute value.

## Prerequisites

- [ScriptRunner](https://marketplace.atlassian.com/apps/6820/scriptrunner-for-jira?tab=overview&hosting=cloud) for Jira

## Configuration

1. Update the following parameters according to your Jira instance:
  - `attributeName`: The name of the attribute to search for (for example, `Serial Number`).
  - `AUTH_HASH`: Base64 encoded authorization hash for a user with `Browse Assets` permission for all asset types. You can generate the hash using `echo -n "username:password" | base64`. Replace `username` and `password` with your Jira credentials.
  - `assetCustomFieldId`: The ID of the custom field containing the asset selections. You can find the ID by right-clicking on the custom field in the issue edit screen and selecting **Copy ID**.
  - `issueKey`: The issue key for the issue where the script is being executed.

### ScriptRunner Groovy script - Tested on script console

<details>
<summary>Script:</summary>

```groovy
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import groovy.json.JsonSlurper
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils
import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.MutableIssue;
import org.apache.commons.lang3.StringUtils;
 
/*********************************************************************************************************/
/*  IMPORTANT:
/*    Configure these settings according to your environment
/*    AUTH_HASH value must be changed according to the user who has Browse Assets for all types */
/*********************************************************************************************************/
def attributeName = 'Serial Number'; // attribute name to search
def AUTH_HASH = 'Basic YWRtaW46YWRtaW4='; // auth hash for authorization. this sample is for user=admin, and password=admin
def assetCustomFieldId = "customfield_10227"; // id of the asset custom field. To find it quickly, right click on issue edit screen where asset custom field appears and find the id of it.
def issueKey = "KTP-28";
/*********************************************************************************************************/ 
 
Logger logger = Logger.getLogger("inventoryplugin.groovy.script")
logger.setLevel(Level.DEBUG)
 
/**
 * Get Asset custom field value
 */
def getCustomFieldValue(issueObj, assetCustomFieldId) {
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def cField = customFieldManager.getCustomFieldObject(assetCustomFieldId)
    return issueObj.getCustomFieldValue(cField);
}

def getAssetAttributeValue(authHash, assetId, attributeName) {
    Logger logger = Logger.getLogger("inventoryplugin.groovy.script")
 
    try {
        if (assetId != null) {
            // get asset ID(s)
            def baseurl = ComponentAccessor.getApplicationProperties().getString("jira.baseurl")
            // this is the search query parameters. It searches for an asset exact asset ID. When you search assets on Asset Navigator,
            // same parameters appear on Developer tools-> Network Tab. You can make different searches and get the parameters from there when you need.
            def queryToPostJson =   '''{
                                      "searchType": "basic",
                                      "listType": "detail",
                                      "genericKeyword": null,
                                      "queryIndexSearchParams": [
                                        {
                                          "field": "asset.id",
                                          "keyword": "",
                                          "keywords": [],
                                          "fieldType": "LONG",
                                          "minNum": '''  + assetId +''',
                                          "maxNum": null,
                                          "minDate": null,
                                          "maxDate": null,
                                          "range": false
                                        }
                                      ],
                                      "pageNumber": 1,
                                      "pageSize": 15,
                                      "sortDirection": "asc",
                                      "sortField": "asset.name"
                                    }''';
 
            CloseableHttpClient httpclient = HttpClients.createDefault();
            def httpPost = new HttpPost(baseurl + "/rest/jip-api/1.0/index/query");
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setHeader("Authorization", authHash);
 
            def entity = new StringEntity(queryToPostJson);
 
            httpPost.setEntity(entity);
            CloseableHttpResponse response = httpclient.execute(httpPost);
            try {
                if (response.getStatusLine().getStatusCode() == 200) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                    br.close();
                    EntityUtils.consume(response.getEntity())
 
                    def jsonSlurper = new JsonSlurper()
                    def json = jsonSlurper.parseText(sb.toString())
                    def assets = json.assets;
                    
                    def returnValue= null;
                    if(assets != null){
                        assets.each { asset ->
                            asset.inventoryItems.each{ assetItem ->
                                if(StringUtils.equalsIgnoreCase(assetItem.attributeName, attributeName)){
                                    // displayValue will return enhanced value. For asset refefence types (InventoryListByForm or InventoryList)  inventoryRefs attribute. 
                                    // example: inventoryRefs: [{id: 26, name: "MOUSE-0001"}]
                                    returnValue = assetItem.value; 
                                }
                            }
                        }
                    }
                    return returnValue;
                } else {
                    return null;
                }
            } finally {
                httpclient.close();
            }
        }
    } catch (Exception e) {
        logger.error("Error while searching assets: " + e.getMessage());
        return null;
    }
}
 
try {
    IssueManager issueMgr = ComponentAccessor.getIssueManager();
    MutableIssue issue = issueMgr.getIssueObject(issueKey)
    logger.debug('Issue key: ' + issueKey);
    logger.debug('Attribute name to search: ' + attributeName);
    
    def assetCfValue = getCustomFieldValue(issue, assetCustomFieldId)
    logger.debug('Asset CF Value: ' + assetCfValue); // i.e: ,217,123,124,
    if(StringUtils.isNotBlank(assetCfValue)){
      def assetIdArray = StringUtils.split(assetCfValue, ',');
        for(def assetId: assetIdArray){
            if(StringUtils.isNotBlank(assetId)){
                logger.debug('Asset Id: ' + assetId);
                def attbiuteValue = getAssetAttributeValue(AUTH_HASH, assetId, attributeName);
                logger.debug('Attribute value: ' + attbiuteValue); 
                // Here you can use the attribute value to set as another custom field's value
            }
        }
    }
        
    
} catch (Exception e) {
    logger.error("Error occurred: " + e.getMessage());
 
}
return null;
```
</details>

### ScriptRunner console logs

<details>
<summary>Console logs:</summary>

```
2019-09-11 17:55:16,770 DEBUG [groovy.script]: Issue key: KTP-28
2019-09-11 17:55:16,770 DEBUG [groovy.script]: Attribute name to search: Serial Number
2019-09-11 17:55:16,770 DEBUG [groovy.script]: Asset CF Value: ,217,123,124,
2019-09-11 17:55:16,771 DEBUG [groovy.script]: Asset Id: 217
2019-09-11 17:55:16,824 DEBUG [groovy.script]: Attribute value: Example serial 00001
2019-09-11 17:55:16,824 DEBUG [groovy.script]: Asset Id: 123
2019-09-11 17:55:16,870 DEBUG [groovy.script]: Attribute value: 1254-4432-3455-6642
2019-09-11 17:55:16,870 DEBUG [groovy.script]: Asset Id: 124
2019-09-11 17:55:16,911 DEBUG [groovy.script]: Attribute value: 3434-4567-322-23445
```
</details>