Absent Member.
Absent Member.
1224 views

Having trouble with the Web Services API using Microsoft Powershell?

Our DBA is having trouble accessing the Web Services API with Microsoft Powershell.  Does anyone have experience using powershell with the Web Services API on the logger?

Labels (3)
0 Likes
7 Replies
Absent Member.
Absent Member.

I'm working through it right now. What I have determined so far is that the New-WebServiceProxy Cmdlet in PS 2.0 will not work. It mangles the wsdl to the point that when you run a Get-Member on the loginservice or searchservice object you create, while the method and property names match the documentation for the most part, the expected number of arguments and expected argument types are completely dissimilar. For instance, look at this code:

#This function allows the script to decode the securestring password

function Decrypt-SecureString([Security.SecureString]$secure)

{

  $marshal = [Runtime.InteropServices.Marshal]

  $marshal::PtrToStringAuto($marshal::SecureStringToBSTR($secure))

}

$login_uri = "https://" + $servername + "/soap/services/LoginService/LoginService.wsdl"

$login_url = "https://" + $servername + "/soap/services/LoginService"

$loginService = New-WebServiceProxy -Uri $login_uri #-Namespace "http://www.arcsight.com/logger/xsd"

$loginService.Url = $login_url


$username = Read-Host "Enter your username"

$password = Read-Host -AsSecureString "Enter your password"

$cookie = $loginService.login($username,(Decrypt-SecureString $password),3600,1)

Notice that the login method is passing 4 parameters, even though the documentation for the API only specifies three. That's because, for whatever reason, the object that New-WebServiceProxy creates expects a 4th parameter. You can see this with Get-Member:

login                                Method     string login(string param0, string param1, int param2, bool param2Specified)


Others are completely mangled such that they only take 1 argument when the API expects 4 (e.g. startSearch for the searchservice object).


Long and short of it is that you can't use New-WebServiceProxy right now. I had to resort to System.Net.WebRequest and System.Net.WebResponse and build the XML manually.                                                      

0 Likes
Absent Member.
Absent Member.

Jason, would you be able to share the WebRequest / WebResponse code you wrote? I'm having the same issue using VS.NET...

0 Likes
Absent Member.
Absent Member.

I wrote up this powershell script to test out the API awhile back when I had a customer that was just asking for some getting started help. So, I was able to use this to test it out. Let me know if this helps.

function MyMain
{
Ignore_SSL

$loginServiceUrl = "https://youlogger/soap/services/LoginService/LoginService.wsdl"
$reportServiceUrl = "https://youlogger/soap/services/ReportLoginService/ReportService.wsdl"
$searchServiceUrl = "https://youlogger/soap/services/SearchService/SearchService.wsdl"


$loginservice = New-WebServiceProxy -uri $loginServiceUrl
$loginservice.URL = $loginServiceUrl

$reportservice = New-WebServiceProxy -uri $reportServiceUrl
$reportservice.Url = $reportServiceUrl

$searchservice = New-WebServiceProxy -uri $searchServiceUrl
$searchservice.URL = $searchServiceUrl

$ver = $loginservice.getVersion()
#$loginservice | get-member
$login = $loginservice.login("admin", "password", 60, "true")

write-host API Version: $ver.return
write-host Login Cookie: $login

#$loginservice |Get-Member -MemberType Method

#$searchservice |Get-Member

$EpochDiff = New-TimeSpan "01 January 1970 00:00:00" $(Get-Date)
$EpochSecs = [INT] $EpochDiff.TotalSeconds

$starttime = ($EpochSecs - 120) * 1000
$endtime = $EpochSecs * 1000

$search = new-object Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy7archService_SearchService_wsdl.startSearch
$search.param0 = "arcsight"
$search.param1 = $starttime
$search.param1Specified = "true"
$search.param2 = $endtime
$search.param2Specified = "true"
$search.param3 = $login

$searchservice.startSearch($search)

$hasMore = new-object system.object
#$searchservice | get-member
$notsure = new-object system.object
$searchservice.hasMoreTuples($login, [ref]$hasmore, [ref]$notsure)

$tuple = new-object Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy7archService_SearchService_wsdl.Tuple
#$tuple | get-member

while($hasmore){
  $tuples = $searchservice.getNextTuples(10, 'true', 100, 'true', $login)
  if ($tuples -ne $null) {
   $tuples
  }
  $searchservice.hasMoreTuples($login, [ref]$hasmore, [ref]$notsure)
}

$logout = new-object Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy5LoginService_LoginService_wsdl.logout
$logout.param0 = $login
$loginservice.logout($logout)
}

function Ignore_SSL
{
$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 TrustAll() {}
    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
}

MyMain

0 Likes
Absent Member.
Absent Member.

Yeah, regarding the 4th parameter, both this and my VS.NET clients have that. The API does not expect 4 parameters, it is when .NET builds the webservice from the WSDL, I think it marks the parameter as optional. So, in our clients, we just have to specify true for the last argument to indicate that you are passing that particular argument. If you don't, the SOAP call will not include the argument and it will fail since the API does expect all three and it really isn't optional.

0 Likes
Absent Member.
Absent Member.

System.Net


System.Net.Security



Module1



Public svcLoginService As LoginService.LoginService = New LoginService.LoginService


Public svcSearchService As SearchService.SearchService = New SearchService.SearchService


Public svcReportService As ReportService.ReportService = New ReportService.ReportService



Dim loggerAddress As String = ""


Dim loggerPort As String = ""


Dim username As String = ""


Dim password As String = ""


Dim sessionTimeout As Integer = 3600


Dim cookie As String = ""


Dim APIVer As String = ""


Dim hasmore As Boolean = False


Dim tupleCount As Integer = 1


Dim tupleTimeout As Integer = 1


Dim recCount As Integer = 0



Sub Main()


'Disable SSL Certificate Validation






My.Settings.LoggerAPIRefClientCLI_LoginService_LoginService


My.Settings.LoggerAPIRefClientCLI_ReportService_ReportService


My.Settings.LoggerAPIRefClientCLI_SearchService_SearchService



Dim gotinfo As Boolean = False


Do Until (gotinfo)


Console.Clear()


Console.WriteLine("Using the following information:")


Console.WriteLine("Username = " & username)


Console.WriteLine("Password = " & password)


Console.WriteLine("Address = " & loggerAddress)


Console.WriteLine("Port = " & loggerPort)



Console.WriteLine("To change values, hit 'n <enter>' else '<enter>':")


Dim myChoice As String = Console.ReadLine()



If myChoice.Trim.ToLower = "n" Then



Else


True


End If


Loop



'Login Routines



Console.Clear()





'Login Info


Console.WriteLine("API Functions Called (As in vb.net):")


Console.WriteLine("login(username, password, sessionTimeout, True)")


Console.WriteLine("getVersion()")


Console.WriteLine()


Console.WriteLine("Login Info:")


Console.WriteLine("Username: " & username)


Console.WriteLine("Password: " & password)


Console.WriteLine("Logger: " & loggerAddress & ":" & loggerPort)


Console.WriteLine("API Version: " & APIVer)


Console.WriteLine("Login Cookie: " & cookie)


Console.WriteLine("Press Enter to continue")


Console.ReadLine()


Console.Clear()



'Search Routines


Console.WriteLine("SearchService Calls:")


Console.WriteLine("startSearch(request)")


Console.WriteLine("hasMoreTuples(cookie, hasmore, True)")


Console.WriteLine("getNextTuples(tupleCount, True, tupleTimeout, True, cookie)")


Console.WriteLine("endSearch(endSearch)")


Console.WriteLine("")






While (hasmore And recCount <= 5)




End While



Console.WriteLine("Press Enter to continue")


Console.ReadLine()


Console.Clear()



'report routines


Console.WriteLine("getReportGroups(cookie)")


Console.WriteLine("")



Console.WriteLine("Press Enter to continue")


Console.ReadLine()


Console.Clear()



Console.WriteLine("getReportsInGroup(""SYSTEM_SANS-TOP-5_"", cookie)")


Console.WriteLine("")



Console.WriteLine("Press Enter to continue")


Console.ReadLine()


Console.Clear()



Console.WriteLine("runReport(reportID, FTime, True, TTime, True, scanLimit, True, resultRowLimit, True, Devices, deviceGroups, storageGroups, reportParameters, reportFormat, cookie)")


Console.WriteLine("")



Console.WriteLine("Press Enter to continue")


Console.ReadLine()


Console.Clear()





End Sub



'**********************************************************************************************


' There are the Logger API Methods we are using. Everything outside of these methods are


' helper methods used to make the client work.


Public Sub login()


Try


True)


Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Private Sub getVersion()


Try


Dim blah As LoginService.getVersionResponse = svcLoginService.getVersion()



Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Public Sub logout()


Try


Dim svcLogout As LoginService.logout = New LoginService.logout




Console.WriteLine("Logged out session: " & cookie)


Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Public Sub runSearch()


Dim stime As DateTime = Date.UtcNow.AddHours(-2)


Dim etime As DateTime = Date.UtcNow



Dim FTime As Long = DateTimeToEpoch(stime)


Dim TTime As Long = DateTimeToEpoch(etime)






Dim query As String = " "


Console.WriteLine("Enter Query: <" & query & ">")


Console.ReadLine().Trim



'MessageBox.Show(FTime & " " & TTime)


Dim request As SearchService.startSearch = New SearchService.startSearch






True


True



Try



Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Public Sub hasMoreTuples()


Try


True)


Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Public Sub getNextTuples()


Try


Dim t() As SearchService.Tuple = svcSearchService.getNextTuples(tupleCount, True, tupleTimeout, True, cookie)


If Not t Is Nothing Then


For Each record As SearchService.Tuple In t


For Each item In record.data


Console.WriteLine(item.Trim())


Next


Console.WriteLine()



Next


End If


Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Private Sub endSearch()


Dim endSearch As SearchService.endSearch = New SearchService.endSearch()



Try



Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



'Report Subs


Sub reportGroups()


Try


Dim ReportGroups() As ReportService.Group = svcReportService.getReportGroups(cookie)


For Each reportGroup In ReportGroups


Console.WriteLine("Name: " & reportGroup.name & " ID:" & reportGroup.id)


Next


Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Sub reportsInGroup()


Try


Dim reports() As ReportService.Report = svcReportService.getReportsInGroup("SYSTEM_SANS-TOP-5_", cookie)


If Not reports Is Nothing Then


For Each report As ReportService.Report In reports


Console.WriteLine("Report Name: " & report.name & " Report ID: " & report.id)


Next


End If


Catch ex As Exception


Console.Write(ex.Message)


End


End Try


End Sub



Sub runReport()


Dim scanLimit As Integer = 1000


Dim resultRowLimit As Integer = 10


Dim Devices As String = ""


Dim deviceGroups As String = ""


Dim storageGroups As String = ""


Dim reportFormat As String = "CSV"


Dim reportID As String = "FFACF97B-9473-9DB8-4A50-D7D7F2D62B00"


Dim reportParameters As String = "" 'If there are parameters, enter them here as paramname=paramvalue


Dim results As String = ""



Dim stime As DateTime = Date.UtcNow.AddHours(-2)


Dim etime As DateTime = Date.UtcNow



Dim FTime As Long = DateTimeToEpoch(stime)


Dim TTime As Long = DateTimeToEpoch(etime)






Try


True, TTime, True, scanLimit, True, _


True, Devices, deviceGroups, storageGroups, reportParameters, _



Catch ex As Exception


Console.Write(ex.Message)


End


End Try



Dim unencoded() As Byte = Convert.FromBase64String(results)


Dim enc As New System.Text.UTF8Encoding()


Console.Write(enc.GetString(unencoded))


Console.WriteLine()


End Sub



' End of Logger API methods


'**********************************************************************************************



'This function is used to convert a DateTimeValue to epoch time. The API expects epoch time formats.


'Remember that epoch is in GMT, so always pass a GMT/UTC time to this function.


Private Function DateTimeToEpoch(ByVal DateTimeValue As Date) As Integer


Try


Return CInt(DateTimeValue.Subtract(CDate("1.1.1970 00:00:00")).TotalSeconds)


Catch ex As System.OverflowException


Return -1


End Try


End Function



Sub getInput()


Console.Clear()


Console.WriteLine("Provide login information. Hit enter to use the default.")


Console.WriteLine("Enter username: <" & username & ">")


Dim usernameInput As String = Console.ReadLine()


Console.WriteLine("Enter password: <" & password & ">")


Dim passwordInput As String = Console.ReadLine()


Console.WriteLine("Enter Logger Address: <" & loggerAddress & ">")


Dim addressInput As String = Console.ReadLine()


Console.WriteLine("Enter Logger Port: <" & loggerPort & ">")


Dim portInput As String = Console.ReadLine()



If (usernameInput.Length > 0) Then



End If


If (passwordInput.Length > 0) Then



End If


If (addressInput.Length > 0) Then



End If


If (portInput.Length > 0) Then



End If


End Sub



'This function updates the app.config settings. The web services use these settings to connect to the API.


'Once you change the settings, they will be saved for future runs.


Private Sub updateSettings()


Dim LoginURLPath = "/soap/services/LoginService/LoginService.wsdl"


Dim SearchURLPath As String = "/soap/services/SearchService/SearchService.wsdl"


Dim ReportURLPath As String = "/soap/services/ReportService/ReportService.wsdl"


My.Settings.LoggerAPIRefClientCLI_LoginService_LoginService = "https://" & loggerAddress & ":" & _



My.Settings.LoggerAPIRefClientCLI_SearchService_SearchService = "https://" & loggerAddress & ":" & _



My.Settings.LoggerAPIRefClientCLI_ReportService_ReportService = "https://" & loggerAddress & ":" & _



My.Settings.username = username


My.Settings.password = password


My.Settings.LoggerAPIRefClientCLI_LoginService_LoginService


My.Settings.LoggerAPIRefClientCLI_ReportService_ReportService


My.Settings.LoggerAPIRefClientCLI_SearchService_SearchService


End Sub



'This method loads the initial settings from app.config.


Private Sub LoadSettings()


Dim url As String = My.Settings.LoggerAPIRefClientCLI_LoginService_LoginService


Dim delim As String() = New String(0) {"://"}


Dim temp1 As Array = url.Split(delim, System.StringSplitOptions.None)


Dim temp2 As Array = temp1(1).Split("/")


Dim temp3 As Array = temp2(0).Split(":")





My.Settings.username


My.Settings.password


End Sub




'**********


' This methods are only used to disable certificate validation, this shouldn't be used in production


Public Sub disableCertValidation()


ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf validateCertificate)


End Sub



Private Function validateCertificate(ByVal sender As Object, ByVal certificate As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean


Return True


End Function


'**********



Module


0 Likes
Cadet 1st Class
Cadet 1st Class

Hi,

Your powershell works. But in the latest Logger version, the Tuple method doesn't seem to exist no more,

Is there another way, or has the method change?

0 Likes
Absent Member.
Absent Member.

I am not sure what call you specifically mean. I am looking at the Logger_WebServicesAPI_5.5.pdf and I see the same tuple calls. One thing that could have changes is the optional parameters. You could try removing the true arguments and play with those. They just specify if an optional parameter is being passed or not. If the wsdl changes and .net doesn't see them as optional anymore, then you might not need the true arguments.

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.