Example code on PowerShell to access Cisco ACS REST API (v5.8.x)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
9.6 KiB

<# === INIT FUNCTIONS === #>
# Hack to accept any unsigned cert on https site
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
# Set accepted remote side SSL/TLS versions and apply cert hack
function Set-TLS {
param()
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}
# Generate HTTP authentication string based on user/pass
function Get-Base64AuthHeader {
param(
[String]$user,
[String]$pass
)
$data = [System.Text.Encoding]::ASCII.GetBytes("$($user):$($pass)")
$payload = [System.Convert]::ToBase64String($data)
$hdr = @{Authorization = "Basic $payload"}
return $hdr
}
# Perform request to ACS server and obtain session variable,
# that later will be re-used for all subsequent requests
function Get-Auth {
param(
[String]$url,
[Hashtable]$hdr
)
$Result = Invoke-WebRequest -UseBasicParsing -Method GET -Uri $url -Headers $hdr -SessionVariable 'Session'
return @{
result = $Result
session = $Session
}
}
<# === MISC FUNCTION EXAMPLES === #>
# Return XML data fror user from ACS internal database with $username
function Get-ACSUserByName {
param(
[String]$acs,
$session,
[String]$username
)
$resturl = "/Rest/Identity/User/name/"
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method GET -Uri "$($acs)$($resturl)$($username)"
return [xml]$result.Content
}
# Get devices that are conform with supplied filter (in XML format)
function Get-FilterDevicesByName {
param(
[String]$acs,
$session,
[xml]$filter
)
$header = @{"Content-type" = "application/xml"}
$resturl = "/Rest/NetworkDevice/Device/op/query"
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Body $filter -Headers $header
return [xml]$result.Content
}
# Get locations list (either all, or that match $filter)
function Get-AllLocations {
param(
[String]$acs,
$session,
[xml]$filter
)
if ($filter -eq $null) {
$resturl = "/Rest/NetworkDevice/DeviceGroup/"
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method GET -Uri "$($acs)$($resturl)"
}
else
{
$header = @{"Content-type" = "application/xml"}
$resturl = "/Rest/NetworkDevice/DeviceGroup/op/query"
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Headers $header -Body $filter
}
return [xml]$result.Content
}
# Get all devices (XML) assigned to $location and save XML to files
function Get-DevicesByLocation {
param(
[String]$acs,
$session,
[String]$location,
[String]$path
)
$header = @{"Content-type" = "application/xml"}
$resturl = "/Rest/NetworkDevice/Device/op/query"
# Create filter from template
[String]$data = Get-Content -Path tpl_location_filter.xml
[xml]$xml = $data -f $location
$xml.Save("$($path)\location_filter.xml")
# Load filter
[xml]$filter = Get-Content -Path "$($path)\location_filter.xml"
# Query devices
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Headers $header -Body $filter
# Loop thru all received devices
$devs = Select-Xml -xml $result -XPath //Device
foreach ($dev in $devs) {
"`t$($dev.node.id);$($dev.node.name);$($dev.node.subnets.ipAddress)" | Out-Host
}
# Remove any special characters and save devices XML on disk
$location_split = $location -replace "\\|:|\/|\?","_"
$parsed.save("$($path)\$($location_split).xml")
}
# Get all devices (TXT) assigned to $location
function Get-DevicesByLocationTXT {
param(
[String]$acs,
$session,
[String]$location,
[String]$path
)
$header = @{"Content-type" = "application/xml"}
$resturl = "/Rest/NetworkDevice/Device/op/query"
# Create filter from template
[String]$data = Get-Content -Path tpl_location_filter.xml
[xml]$xml = $data -f $location
$xml.Save("$($path)\location_filter.xml")
# Load filter
[xml]$filter = Get-Content -Path "$($path)\location_filter.xml"
# Query devices
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Headers $header -Body $filter
# Format result
$result.Content | Set-Content -Path tmp_devices.xml
$parsed = [xml](Get-Content tmp_devices.xml)
# Loop thru all received devices
$devs = Select-Xml -xml $parsed -XPath //Device
$list = @()
foreach ($dev in $devs) {
"`t$($dev.node.name)" | Write-Host
$list += $dev.node.name
}
return $list
}
# Find location by Name and return its XML
function Get-LocationIDByName {
param(
[String]$acs,
$session,
[String]$location
)
$resturl = "/Rest/NetworkDevice/DeviceGroup/name/Location:$($location)"
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method GET -Uri "$($acs)$($resturl)"
return [xml]$result.Content
}
# Find device by Name and return its XML
function Get-DeviceByName {
param(
[String]$acs,
$session,
[String]$name
)
$resturl = "/Rest/NetworkDevice/Device/name/$($name)"
try
{
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method GET -Uri "$($acs)$($resturl)"
}
catch
{
"Error occured during data retrieval for $($name)" | Write-Host
return
}
return [xml]$result.Content
}
# Delete location by its ID
function Del-LocationByID {
param(
[String]$acs,
$session,
[String]$loc_id
)
$resturl = "/Rest/NetworkDevice/DeviceGroup/id/$($loc_id)"
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method DELETE -Uri "$($acs)$($resturl)"
return $result
}
# Update device (XML obj) Location
function Upd-DeviceLocation {
param(
[String]$acs,
$session,
[xml]$device,
[String]$newloc
)
$resturl = "/Rest/NetworkDevice/Device"
$header = @{"Content-type" = "application/xml"}
[xml]$obj = $device
"Editing device $($obj.device.name)... " | Write-Host -NoNewline
foreach ($gi in $obj.device.groupInfo) {
if ($gi.groupType -eq "Location") {
$old = $gi.groupName
$gi.groupName = $newloc
break
}
}
try
{
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Headers $header -Body $obj
"Location changed from $($old) to $($newloc)" | Write-Host
}
catch
{
"FAILED!" | Write-Host
return
}
}
# Update device (XML obj) Type
function Upd-DeviceType {
param(
[String]$acs,
$session,
[xml]$device,
[String]$newtype
)
$resturl = "/Rest/NetworkDevice/Device"
$header = @{"Content-type" = "application/xml"}
[xml]$obj = $device
"Editing device $($obj.device.name)... " | Write-Host -NoNewline
foreach ($gi in $obj.device.groupInfo) {
if ($gi.groupType -eq "Device Type") {
$old = $gi.groupName
$gi.groupName = $newtype
break
}
}
try
{
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Headers $header -Body $obj
"OK! Device type changed from $($old) to $($newtype)" | Write-Host
}
catch
{
"FAILED!" | Write-Host
return
}
}
# Update user (XML obj) Identity group
function Upd-UserIdentityGroup {
param(
[String]$acs,
$session,
[xml]$user,
[String]$newig
)
$resturl = "/Rest/Identity/User"
$header = @{"Content-type" = "application/xml"}
[xml]$obj = $user
"Changing IG for user $($obj.user.name)... " | Write-Host -NoNewline
$old = $obj.user.identityGroupName
$obj.user.identityGroupName = $newig
try
{
$result = Invoke-WebRequest -UseBasicParsing -WebSession $session -Method PUT -Uri "$($acs)$($resturl)" -Headers $header -Body $obj
"OK! $($old) -> $($newig)" | Write-Host
}
catch
{
"FAILED!" | Write-Host
return
}
}
<# === STARTUP, AUTH TOKEN RETRIEVAL === #>
# Apply HTTPS cert hack
Set-TLS
# Load ACS auth credentials
$credential = Import-Clixml -Path ACScreds.xml
$u = $credential.UserName
$p = $credential.Password
# OR
# put credentials manualy
#$u = "username"
#$p = Read-Host 'Enter password' -AsSecureString
# Decode secure password to 'usable' condition. It will be used only once, then cleared.
$clearpass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($p))
# ACS Host base URL
$ACSHost = "https://1.2.3.4"
# Obtain auth token
$auth = Get-Base64AuthHeader -user $u -pass $clearpass
$clearpass = ""
# Try to authenticate and obtain session
$auth_url = $ACSHost + "/Rest/Common/AcsVersion"
$rest_result = Get-Auth -url $auth_url -hdr $auth
if ($rest_result['result'] -eq $null) {
"Authentication failed!" | Write-Host
exit
}
else
{
"$($auth_url): Authenticated" | Write-Host
}
# Get current script path
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition