<# === 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