New-WebServiceProxy.ps1 by Oisin Grehan 3 years ago (modification of post by Oisin Grehan view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1340"></script>download | new post
compatibility: PowerShell 1.0, PowerShell v2.0
UPDATE: bugfix to get correct $serviceType if $namespace provided
UPDATE: now supports -Namespace parameter to differentiate different proxies that may use the same type names. e.g.:
$p1 = new-webserviceproxy -anonymous http://foo/foo.asmx -namespace service1
$c1 = new-object service1.usercredentials “foo”, “bar”
$p2 = new-webserviceproxy -anonymous http://foo/foo2.asmx -namespace service2
$c2 = new-object service2.usercredentials “foo”, “bar”
—
Many simple webservice scripts can not handle more complex webservices like the MSDN ContentService for example, so I wrote this script from the ground up and modeled it on the .NET SDK’s WSDL.EXE. It supports Basic Profile 1.1 and can generate proxy instances for simple ASMX services and more complicated multi-schema services like the MSDN/TechNet Publishing System (MTPS) Content Service.
- No need for the .NET 2.0 SDK, just PowerShell
- Auto discovery of all referenced schema
- No need to point it at page.asmx?wsdl any more, just the asmx
- Validation against WS-I Basic Profile 1.1
By default, it asks for credentials. If targetting a public webservice, specify the -Anonymous switch.
- #
- # New-WebServiceProxy.ps1 (v3.0 Sep 23, 2009)
- #
- # Oisin Grehan <oising@gmail.com> (x0n)
- #
- # Usage:
- # $proxy = .\New-WebServiceProxy.ps1 [-Url] http://site/service.asmx [-Anonymous] [[-SoapProtocol] <Soap | Soap12>] [-Namespace <namespace>]
- #
- # to see available webmethods:
- # $proxy | gm
- #
- # $url = "http://services.msdn.microsoft.com/contentservices/contentservice.asmx?wsdl"
- param($url = $(throw "need `$url"), [switch]$Anonymous, [string]$protocol = "Soap", [string]$Namespace="")
- [void][system.Reflection.Assembly]::LoadWithPartialName("system.web.services")
- trap {
- "Error:`n`n $error";
- break;
- }
- #$request = [System.Net.WebRequest]::Create($url);
- $dcp = new-object system.web.services.discovery.discoveryclientprotocol
- if (! $Anonymous) {
- Write-Progress "Network Credentials" "Awaiting input..."
- $dcp.Credentials = (Get-Credential).GetNetworkCredential()
- }
- Write-Progress "Discovery" "Searching..."
- $dcp.AllowAutoRedirect = $true
- [void]$dcp.DiscoverAny($url)
- $dcp.ResolveAll()
- # get service name
- foreach ($entry in $dcp.Documents.GetEnumerator()) { # needed for Dictionary
- if ($entry.Value -is [System.Web.Services.Description.ServiceDescription]) {
- $script:serviceName = $entry.Value.Services[0].Name
- Write-Verbose "Service: $serviceName"
- }
- }
- Write-Progress "WS-I Basic Profile 1.1" "Validating..."
- $ns = new-Object System.CodeDom.CodeNamespace $Namespace
- $wref = new-object System.Web.Services.Description.WebReference $dcp.Documents, $ns
- $wrefs = new-object system.web.services.description.webreferencecollection
- [void]$wrefs.Add($wref)
- $ccUnit = new-object System.CodeDom.CodeCompileUnit
- [void]$ccUnit.Namespaces.Add($ns)
- $violations = new-object system.web.Services.Description.BasicProfileViolationCollection
- $wsi11 = [system.web.services.WsiProfiles]::BasicProfile1_1
- if ([system.web.Services.Description.WebServicesInteroperability]::CheckConformance($wsi11, $wref, $violations)) {
- Write-Progress "Proxy Generation" "Compiling..."
- $webRefOpts = new-object System.Web.Services.Description.WebReferenceOptions
- $webRefOpts.CodeGenerationOptions = "GenerateNewAsync","GenerateProperties" #,"GenerateOldAsync"
- #StringCollection strings = ServiceDescriptionImporter.GenerateWebReferences(
- # webReferences, codeProvider, codeCompileUnit, parameters.GetWebReferenceOptions());
- $csprovider = new-object Microsoft.CSharp.CSharpCodeProvider
- $warnings = [System.Web.Services.Description.ServiceDescriptionImporter]::GenerateWebReferences(
- $wrefs, $csprovider, $ccunit, $webRefOpts)
- if ($warnings.Count -eq 0) {
- $param = new-object system.CodeDom.Compiler.CompilerParameters
- [void]$param.ReferencedAssemblies.Add("System.Xml.dll")
- [void]$param.ReferencedAssemblies.Add("System.Web.Services.dll")
- $param.GenerateInMemory = $true;
- #$param.TempFiles = (new-object System.CodeDom.Compiler.TempFileCollection "c:\temp", $true)
- $param.GenerateExecutable = $false;
- #$param.OutputAssembly = "$($ns.Name)_$($sdname).dll"
- $param.TreatWarningsAsErrors = $false;
- $param.WarningLevel = 4;
- # do it
- $compileResults = $csprovider.CompileAssemblyFromDom($param, $ccUnit);
- if ($compileResults.Errors.Count -gt 0) {
- Write-Progress "Proxy Generation" "Failed."
- foreach ($output in $compileResults.Output) { write-host $output }
- foreach ($err in $compileResults.Errors) { write-warning $err }
- } else {
- $assembly = $compileResults.CompiledAssembly
- if ($assembly) {
- if ($namespace) {
- $serviceType = $assembly.GetType($namespace + "." + $serviceName)
- } else {
- $serviceType = $assembly.GetType($serviceName)
- }
- $assembly.GetTypes() | % { Write-Verbose $_.FullName }
- } else {
- Write-Warning "Failed: `$assembly is null"
- return
- }
- # return proxy instance
- $proxy = new-object $serviceType.FullName
- if (! $Anonymous) {
- $proxy.Credentials = $dcp.Credentials
- }
- $proxy # dump instance to pipeline
- }
- } else {
- Write-Progress "Proxy Generation" "Failed."
- Write-Warning $warnings
- }
- #Write-Progress -Completed
- }
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
PowerShell Code Repository