asset-management

Asset Management for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "asset-management" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-asset-management

Asset Management for ServiceNow

Asset Management tracks hardware and software assets throughout their lifecycle.

Asset Architecture

Asset (alm_asset) ├── Hardware Asset (alm_hardware) │ └── Consumable (alm_consumable) └── License (alm_license)

CI (cmdb_ci) ←→ Asset (alm_asset) ↑ One CI can have multiple assets over time

Key Tables

Table Purpose

alm_asset

Base asset table

alm_hardware

Hardware assets

alm_license

Software licenses

alm_consumable

Consumable assets

ast_contract

Asset contracts

cmdb_ci

Configuration items

Hardware Assets (ES5)

Create Hardware Asset

// Create hardware asset (ES5 ONLY!) var asset = new GlideRecord("alm_hardware") asset.initialize()

// Basic info asset.setValue("display_name", "Dell Latitude 5520") asset.setValue("asset_tag", "ASSET-" + generateAssetTag()) asset.setValue("serial_number", "SN123456789")

// Model asset.setValue("model", getModelSysId("Dell Latitude 5520")) asset.setValue("model_category", getModelCategorySysId("Laptop"))

// Status and substatus asset.setValue("install_status", 1) // Installed asset.setValue("substatus", "in_use")

// Assignment asset.setValue("assigned_to", userSysId) asset.setValue("assigned", new GlideDateTime()) asset.setValue("location", locationSysId) asset.setValue("department", departmentSysId)

// Financial asset.setValue("cost", 1299.99) asset.setValue("cost_center", costCenterSysId)

// Dates asset.setValue("purchase_date", "2024-01-15") asset.setValue("warranty_expiration", "2027-01-15")

// Link to CI if exists asset.setValue("ci", cmdbCiSysId)

asset.insert()

Asset Lifecycle States

// Asset install_status values var ASSET_STATUS = { INSTALLED: 1, // In use ON_ORDER: 2, // Ordered, not received IN_STOCK: 6, // In inventory IN_TRANSIT: 7, // Being shipped IN_MAINTENANCE: 8, // Under repair RETIRED: 9, // End of life DISPOSED: 10, // Disposed of }

// Transition asset status (ES5 ONLY!) function transitionAssetStatus(assetSysId, newStatus, notes) { var asset = new GlideRecord("alm_hardware") if (!asset.get(assetSysId)) { return { success: false, message: "Asset not found" } }

var currentStatus = parseInt(asset.getValue("install_status"), 10)

// Validate transition var validTransitions = { 2: [6, 7], // On Order -> In Stock, In Transit 7: [6, 1], // In Transit -> In Stock, Installed 6: [1, 7, 9], // In Stock -> Installed, In Transit, Retired 1: [8, 6, 9], // Installed -> In Maintenance, In Stock, Retired 8: [1, 6, 9], // In Maintenance -> Installed, In Stock, Retired 9: [10], // Retired -> Disposed }

if (!validTransitions[currentStatus] || validTransitions[currentStatus].indexOf(newStatus) === -1) { return { success: false, message: "Invalid transition from " + currentStatus + " to " + newStatus, } }

// Update status asset.setValue("install_status", newStatus)

// Handle specific transitions if (newStatus === 1) { asset.setValue("installed", new GlideDateTime()) } else if (newStatus === 9) { asset.setValue("retired", new GlideDateTime()) asset.setValue("assigned_to", "") } else if (newStatus === 10) { asset.setValue("disposed", new GlideDateTime()) }

// Add work note if (notes) { asset.work_notes = notes }

asset.update()

return { success: true, asset_tag: asset.getValue("asset_tag") } }

Software Licenses (ES5)

Create License Record

// Create software license (ES5 ONLY!) var license = new GlideRecord("alm_license") license.initialize()

// Basic info license.setValue("display_name", "Microsoft Office 365 E3") license.setValue("product", getProductSysId("Microsoft Office 365")) license.setValue("license_type", "per_user") // per_user, per_device, site, enterprise

// Quantities license.setValue("rights", 500) // Total licenses purchased license.setValue("used", 0) // Will be calculated license.setValue("remaining", 500) // Will be calculated

// Dates license.setValue("start_date", "2024-01-01") license.setValue("end_date", "2024-12-31")

// Cost license.setValue("cost", 25000.0) license.setValue("cost_per_unit", 50.0)

// Vendor license.setValue("vendor", vendorSysId) license.setValue("contract", contractSysId)

license.insert()

License Allocation

// Allocate license to user (ES5 ONLY!) function allocateLicense(licenseSysId, userSysId) { var license = new GlideRecord("alm_license") if (!license.get(licenseSysId)) { return { success: false, message: "License not found" } }

// Check availability var remaining = parseInt(license.getValue("remaining"), 10) if (remaining <= 0) { return { success: false, message: "No licenses available" } }

// Check if user already has this license var existing = new GlideRecord("alm_entitlement_user") existing.addQuery("licensed_by", licenseSysId) existing.addQuery("user", userSysId) existing.query()

if (existing.hasNext()) { return { success: false, message: "User already has this license" } }

// Create entitlement var entitlement = new GlideRecord("alm_entitlement_user") entitlement.initialize() entitlement.setValue("licensed_by", licenseSysId) entitlement.setValue("user", userSysId) entitlement.setValue("allocated", new GlideDateTime()) entitlement.insert()

// Update license counts updateLicenseCounts(licenseSysId)

return { success: true, message: "License allocated", entitlement: entitlement.getUniqueValue(), } }

function updateLicenseCounts(licenseSysId) { var license = new GlideRecord("alm_license") if (!license.get(licenseSysId)) return

// Count allocations var ga = new GlideAggregate("alm_entitlement_user") ga.addQuery("licensed_by", licenseSysId) ga.addAggregate("COUNT") ga.query()

var used = 0 if (ga.next()) { used = parseInt(ga.getAggregate("COUNT"), 10) }

var rights = parseInt(license.getValue("rights"), 10)

license.setValue("used", used) license.setValue("remaining", rights - used) license.update() }

Asset Discovery Integration (ES5)

Match Discovered CI to Asset

// Match discovered CI to existing asset (ES5 ONLY!) function matchCIToAsset(ciSysId) { var ci = new GlideRecord("cmdb_ci_computer") if (!ci.get(ciSysId)) { return null }

var serialNumber = ci.getValue("serial_number") var assetTag = ci.getValue("asset_tag")

// Try to find matching asset var asset = new GlideRecord("alm_hardware")

// Match by serial number first if (serialNumber) { asset.addQuery("serial_number", serialNumber) asset.query() if (asset.next()) { return linkAssetToCI(asset, ci) } }

// Match by asset tag if (assetTag) { asset = new GlideRecord("alm_hardware") asset.addQuery("asset_tag", assetTag) asset.query() if (asset.next()) { return linkAssetToCI(asset, ci) } }

// No match - create new asset return createAssetFromCI(ci) }

function linkAssetToCI(asset, ci) { asset.setValue("ci", ci.getUniqueValue()) asset.update()

ci.setValue("asset", asset.getUniqueValue()) ci.update()

return asset.getUniqueValue() }

function createAssetFromCI(ci) { var asset = new GlideRecord("alm_hardware") asset.initialize() asset.setValue("display_name", ci.getDisplayValue()) asset.setValue("serial_number", ci.getValue("serial_number")) asset.setValue("asset_tag", ci.getValue("asset_tag")) asset.setValue("model", ci.getValue("model_id")) asset.setValue("ci", ci.getUniqueValue()) asset.setValue("install_status", 1)

var assetSysId = asset.insert()

ci.setValue("asset", assetSysId) ci.update()

return assetSysId }

Asset Reports (ES5)

Asset Inventory Summary

// Get asset inventory summary (ES5 ONLY!) function getAssetInventorySummary() { var summary = { by_status: {}, by_category: {}, by_location: {}, total_value: 0, }

// By status var ga = new GlideAggregate("alm_hardware") ga.addAggregate("COUNT") ga.addAggregate("SUM", "cost") ga.groupBy("install_status") ga.query()

while (ga.next()) { var status = ga.install_status.getDisplayValue() summary.by_status[status] = { count: parseInt(ga.getAggregate("COUNT"), 10), value: parseFloat(ga.getAggregate("SUM", "cost")) || 0, } summary.total_value += summary.by_status[status].value }

// By model category ga = new GlideAggregate("alm_hardware") ga.addAggregate("COUNT") ga.groupBy("model_category") ga.query()

while (ga.next()) { var category = ga.model_category.getDisplayValue() || "Uncategorized" summary.by_category[category] = parseInt(ga.getAggregate("COUNT"), 10) }

// By location ga = new GlideAggregate("alm_hardware") ga.addQuery("install_status", 1) // Only installed ga.addAggregate("COUNT") ga.groupBy("location") ga.query()

while (ga.next()) { var location = ga.location.getDisplayValue() || "Unknown" summary.by_location[location] = parseInt(ga.getAggregate("COUNT"), 10) }

return summary }

MCP Tool Integration

Available Tools

Tool Purpose

snow_query_table

Query assets and licenses

snow_cmdb_search

Search CMDB for CIs

snow_execute_script_with_output

Test asset scripts

snow_find_artifact

Find asset configurations

Example Workflow

// 1. Query hardware assets await snow_query_table({ table: "alm_hardware", query: "install_status=1", fields: "asset_tag,display_name,assigned_to,location,model", })

// 2. Check license compliance await snow_execute_script_with_output({ script: var license = new GlideRecord('alm_license'); license.addQuery('remainingRELATIVELT@integer@0'); license.query(); while (license.next()) { gs.info('Over-allocated: ' + license.display_name); } , })

// 3. Find assets nearing warranty expiration await snow_query_table({ table: "alm_hardware", query: "warranty_expirationBETWEENjavascript:gs.beginningOfToday()@javascript:gs.daysAgoEnd(-30)", fields: "asset_tag,display_name,warranty_expiration,assigned_to", })

Best Practices

  • Asset Tags - Unique, scannable identifiers

  • Lifecycle Tracking - Track all state changes

  • CI Linking - Connect assets to CMDB

  • License Compliance - Monitor allocation vs rights

  • Warranty Tracking - Alert before expiration

  • Financial Accuracy - Maintain cost data

  • Regular Audits - Verify physical inventory

  • ES5 Only - No modern JavaScript syntax

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review
General

scheduled-jobs

No summary provided by upstream source.

Repository SourceNeeds Review
General

document-management

No summary provided by upstream source.

Repository SourceNeeds Review
General

reporting-dashboards

No summary provided by upstream source.

Repository SourceNeeds Review