- Trying to get the powershell Invoke-RestMethod to interact with the Prime Infrastructure API, but not having much luck. Basically want to retrieve a list of devices from the PI API, but not sure what to put in the body for the Invoke-RestMethod command.
- Were you able to connect to the server. Did you have a chance to read the tutorial. There's some detailed info. Haven't tried other REST applications though.
First, if you have a self-signed certificate for Prime Infrastructure, your requests will likely fail with the error message
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
So you'll need to get around this by setting up a new certificate policy to trust all certs. To do that, I found an example on Stack Overflow, and it worked when I tested it. Note that this certificate policy will apply to the entire PowerShell session, so use this workaround at your risk.
Next, you'll need to prepare the authentication info. You can either create a variable with your base64 encoded username:password string, or have PowerShell do the encoding for you with the following code
$basicAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("username:password")))
Now, you're ready to make the actual call. The certificate policy (if you decided to use it) is session global, so the only thing you need to have when you make the invoke is the base64 authentication string and the URL. Here's an example
$response = Invoke-RestMethod "https://my_server/webacs/api/v1/data/Devices" -headers @{Authorization=("Basic {0}" -f $basicAuth)}
you might be looking for:
$response.queryResponse.entity.DevicesDTO | select devicename, devicetype, ipaddress, location
Now for some reason, I'm getting a 401 error :-(. I think prime might be busy !
UPDATE:
Figured out that the -DisableKeepAlive is a must with the invoke-restmethod cmdlet since Prime only allows 5 concurrent connections so in trying various steps I basically locked myself out.
Another trick to get one final variable to hold all the device info which I ended up with is to use this line:
$DeviceInfo = $((Invoke-RestMethod "https://myserver/webacs/api/v1/data/Devices?.full=true" -DisableKeepAlive -headers @{Authorization=("Basic {0}" -f $basicAuth)}) | select @{n="DeviceInfo";e={$_.queryResponse.entity.DevicesDTO}}).deviceinfo
Then you can $DeviceInfo | select whatever.. or $DeviceInfo | out-gridview to see everything in powershell's grid from which you can copy/paste or filter columns.
- Tried that method and I'm getting the error:
Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
- Tried multiple callback functions that found across the web including the Stack Exchange link mentioned that trusts all certs. None of them have worked.
The code is as below:
function Ignore-SSLCertificates
{
$Provider = New-Object Microsoft.CSharp.CSharpCodeProvider
$Compiler = $Provider.CreateCompiler()
$Params = New-Object System.CodeDom.Compiler.CompilerParameters
$Params.GenerateExecutable = $false
$Params.GenerateInMemory = $true
$Params.IncludeDebugInformation = $false
$Params.ReferencedAssemblies.Add("System.DLL") > $null
$TASource=@'
namespace Local.ToolkitExtensions.Net.CertificatePolicy
{
public class TrustAll : System.Net.ICertificatePolicy
{
public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem)
{
return true;
}
}
}
'@
$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
$TAAssembly=$TAResults.CompiledAssembly
## We create an instance of TrustAll and attach it to the ServicePointManager
$TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
[System.Net.ServicePointManager]::CertificatePolicy = $TrustAll
$basicAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("username:password")))
$url = 'https://hostname/webacs/api/v1/data/Devices'
$response = Invoke-RestMethod $url -headers @{Authorization=("Basic {0}" -f $basicAuth)}
Had the same issue at the beginning and used the other cert method which worked.
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; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Followed by the $basicAuth..., $url..., $response (or even beter my $deviceinfo=... which I've included above.)
Tried
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
But every Invoke-RestMethod tried after that failed with the same error message you're seeing, about an unexpected error occuring during a send. When you ran into it, the easiest way found to clear that error was to start a new PowerShell session.
After implementing the certificate policy instead, in a new window, things started working. Hope that helps.
Also, just in case it proves relevant, here's the $PSVersionTable of my PowerShell.
Name | Value |
---|---|
PSVersion | 4.0 |
WSManStackVersion | 3.0 |
SerializationVersion | 1.1.0.1 |
CLRVersion | 4.0.30319.34209 |
BuildVersion | 6.3.9600.16406 |
PSCompatibleVersions | {1.0, 2.0, 3.0, 4.0} |
PSRemotingProtocolVersion | 2.2 |
- Getting a 401 error. Tried the DisableKeepAlive but still no luck. The credentials work for sure. Is there anything else should be tried to get this to go through. will try restarting my powershell setting again.
It could be that there already are 5 concurrent sessions for your user. If possible, you could try restarting the Prime Infrastructure appliance. Or you could try creating a new user.
Also you need to wait a while before retrying again. Prime most probably has a timing threshold (maybe 15min.) before allowing connection again.
- Manually encoded the username:password string to base64 using a website converter and changed the quotes on the URL string to a double quote instead of single quote and it worked after that. Now, curious how to get a complete list of devices. It is only showing 100 devices at a time and it looks like there are over 2300.
That is called "pagination". You can "page" through the results using multiple calls
.maxResults - is the number of devices to return.
.firstResult - is the place to start from. (Initially 1).
#NOTE: there is a "." for each of these keys.
this would get the next 50 results after the first 100.
requestUrl="https://my_server/webacs/api/v1/data/Devices?.full=true&.maxResults=50&.firstResult=100"
Comments
0 comments
Please sign in to leave a comment.