In Powershell to consume a Soap complexType to keep a Soap service hot

12,628

Solution 1

I followed the link that Christian (credit should go to him, but I do not know how to do that) gave and used the default namespace instead. So now I do not need to restart powershell everytime. Maybe there is another solution to kill the fundSrvc object after each call. But I gave up and went with using the default created crazy long namespace.

Here is the solution that works:

#note no -Namespace argument  
$fundSrvc = New-WebServiceProxy -uri "http://myColdServer/WSFund.svc?wsdl"


#get autogenerated namespace
$type = $fundSrvc.GetType().Namespace
$myFundGooferDt = ($type + '.FundInput')
$myFundDt = ($type + '.Fund')
$myInputContextDt = ($type + '.Context') 
$myFundIdentityDt = ($type + '.FundIdentity') 
# Create the Objects needed
$myFundGoofer = new-object ($myFundGooferDt) 
$myFund = new-object ($myFundDt) 
$myInputContext = new-object ($myInputContextDt)
$myFundIdentity = New-Object $myFundIdentityDt
# Assign values
$myFundIdentity.Isin="SE9900558666"
$myFundIdentity.FundBaseCurrencyId="SEK"
$myInputContext.ExtChannelId="ChannelMan"
$myInputContext.ExtId="RubberDuck"
$myInputContext.ExtPosReference="RubberDuck"
$myInputContext.ExtUser="RubberDuck"
$myInputContext.LanguageId="809"
$myFund.Identity=$myFundIdentity

$myFundGoofer.Fund = $myFund
$myFundGoofer.InputContext = $myInputContext

#Tada
$fundSrvc.Get($myFundGoofer)

Solution 2

Your original technique is right, you just need to also include the -class parameter on New-WebServiceProxy. Leave the rest of your code as-is.

I had this exact problem while working with a webservice from PowerShell yesterday. I also had it working by discovering the auto-generated namespace, but that felt a bit too hacky for my liking.

Then I found the solution mentioned here: https://groups.google.com/d/msg/microsoft.public.windows.powershell/JWB5yueLtrg/k0zeUUxAkTMJ

$newWebService = New-WebServiceProxy -uri "http://<server>/webservices/services.php?wsdl" -NameSpace "Service" -Class "<classname>"
Share:
12,628

Related videos on Youtube

Patrik Lindström
Author by

Patrik Lindström

I work as DevOps engineer. I am interested in C#, javascript and Powershell. I try to learn rust and become better at AWS and Linux. I use GitHub Enterprise, AzureDevOps,Jira, Octopus Deploy and Splunk as tool in my work. Here is my linked in profile.

Updated on September 14, 2022

Comments

  • Patrik Lindström
    Patrik Lindström over 1 year

    I am writing a powershell script that will ping a soap webservice every 10 min to keep it hot and alive so performance will increase. We have tryed numerous techniques in the IIS with application pool idle timeout and just making http req for the wsdl. But it seems that we have to make real request that goes down to the sql server else an idle for 90 min will make it to slow for the requirements.

    I have to construct a rather complex search object to be able to make a smart search that will keep the servicelayer cached and hot. The Soap Request Should look like this:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fund="http://www.example.com/cmw/fff/fund" xmlns:tcm="http://www.example.com/cmw/fff/">
       <soapenv:Body>
         <fund:Get>
            <!--Optional:-->
            <fund:inputDTO>
               <fund:Fund>
                  <fund:Identity>
                     <fund:Isin>SE9900558666</fund:Isin>
                     <fund:FundBaseCurrencyId>SEK</fund:FundBaseCurrencyId>
                  </fund:Identity>
               </fund:Fund>
               <fund:InputContext>
                  <tcm:ExtChannelId>Channelman</tcm:ExtChannelId>
                  <tcm:ExtId>Rubberduck</tcm:ExtId>
                  <tcm:ExtPosReference>Rubberduck</tcm:ExtPosReference>
                  <tcm:ExtUser>Rubberduck</tcm:ExtUser>
                  <tcm:LanguageId>809</tcm:LanguageId>
               </fund:InputContext>
            </fund:inputDTO>
         </fund:Get>
       </soapenv:Body>
    </soapenv:Envelope>`
    

    I try to use the New-WebServiceProxy which work so elegantly in this example by powershellguy. I construct my own Objects as this example from technet.

    The powershell code I tried so far is this:

    $fundSrvc = New-WebServiceProxy -uri http://myColdServer:82/WSFund.svc?wsdl -NameSpace "tcm"
    # all the type are now defined since we called New-WebServiceProxy they are prefixed
    # with ns tcm
    [tcm.FundInput] $myFundGoofer = new-object tcm.FundInput 
    [tcm.Fund] $myFund = new-object tcm.Fund
    [tcm.Context] $myInputContext = new-object tcm.Context
    [tcm.FundIdentity] $myFundIdentity = New-Object tcm.FundIdentity
    # Use these commands to get member of the objects you want to investigat
    # $myFundGoofer |Get-Member
    # $myFund |Get-Member
    # $myInputContext |Get-Member
    # $myFundIdentity |Get-Member
    $myFundIdentity.Isin="SE9900558666"
    $myFundIdentity.FundBaseCurrencyId="SEK"
    $myInputContext.ExtChannelId="ChannelMan"
    $myInputContext.ExtId="RubberDuck"
    $myInputContext.ExtPosReference="RubberDuck"
    $myInputContext.ExtUser="RubberDuck"
    $myInputContext.LanguageId="809"
    $myFund.Identity=$myFundIdentity
    
    $myFundGoofer.Fund = $myFund
    $myFundGoofer.InputContext = $myInputContext
    
    #Tada
    $fundSrvc.Get($myFundGoofer)
    

    The Error Message does not make sense to me. Its sounds like: Cannot convert the "tcm.FundInput" value of type "tcm.FundInput" to type "tcm.FundInput"

    Cannot convert argument "0", with value: "tcm.FundInput", for "Get" to type "tcm.FundInput": "Cannot convert the "tcm.FundInput" value of type "tcm.FundInput" to type "tcm.FundInput"."
    At C:\scripts\Service-TestTCM6.ps1:31 char:14
    + $fundSrvc.Get <<<< ($myFundGoofer)
        + CategoryInfo          : NotSpecified: (:) [], MethodException
        + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
    
  • Falco Alexander
    Falco Alexander about 8 years
    can you please add a short example?