commit 0d1b705ef33d5ff5c491b198ac147ac46027db4f Author: Andrey Prokhorov Date: Sun Feb 3 23:56:17 2019 +0200 Initial commit diff --git a/ACSrest.ps1 b/ACSrest.ps1 new file mode 100644 index 0000000..2e769a0 --- /dev/null +++ b/ACSrest.ps1 @@ -0,0 +1,349 @@ +<# === 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 $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 $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 $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 + + # 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 + 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 $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 $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