views:

401

answers:

4

I have a scheduled task which executes a powershell script every hour. The powershell script must make a call to a one-way WCF service operation. Essentially it just needs to kick off an operation. My question is how do i go about doing that? I thought that just executing the url would in fact kick off the request but apparently that is not correct.

Here is what I was trying to do:

$request = [System.Net.WebRequest]::Create("http://myserver.com/myservice/dosomething") $request.GetResponse()

The operation accepts no parameters and returns void.

Any help is much appreciated.

+1  A: 

had a quick look around, this might help you out

Calling a Web Service from PowerShell

djl
I now want to learn more about PowerShell to test out web services that I write. Good link!
arabian tiger
Well this will need to be run on a production server. I doubt we'll have the ability (or want) to install visual studio on our prod boxes. I'll have to explore pre-generating the wsdl.
devlife
A: 

I believe that you'll need to set the HTTP method first before attempting to get a response. By default, I believe the WebRequest object defaults to POST, but you'll actually need to set it to GET.

I haven't used PowerShell scripting much, but based off of your sample it would look something like this:

$request = [System.Net.WebRequest]::Create("http://myserver.com/myservice/dosomething") 
$request.Method = "GET"
$request.GetResponse()

Hope that helps!

arabian tiger
In order to do this would I only have to expose the operation with a WebGet attribute and expose a RESTful endpoint?
devlife
+1  A: 

I think the problem is that the code you have is actually creating an HttpWebRequest, not a WCF request. (In other words, it's simply executing an HTTP GET request on the URL, with no SOAP or .NET Remoting information.)

You should be able to follow these instructions to create a proper endpoint:

http://msdn.microsoft.com/en-us/magazine/cc163647.aspx#S11

It should look something like this:

$httpBinding = New-Object System.ServiceModel.BasicHttpBinding
$endpointAddress = New-Object System.ServiceModel.EndpointAddress 'http://myserver.com/myservice/dosomething'
$contractDescription = [System.ServiceModel.Description.ContractDescription]::GetContract([IYourInterface], $httpBinding, $endpointAddress)
$serviceEndpoint = New-Object System.ServiceModel.Description.ServiceEndpoint $contractDescription
$channelFactory = New-Object "System.ServiceModel.ChannelFactory``1[IYourInterface]" $serviceEndpoint
$webProxy = $channelFactory.CreateChannel();
$webProxy.yourServiceMethod();

Note that you'll need to import the DLL with the IYourInterface class for this to work:

[void] [Reflection.Assembly]::LoadFrom('path/to/your.dll')

Alternatively, if you have a WSDL defined for the service, you can follow these much easier instructions to access the service:

http://blogs.technet.com/heyscriptingguy/archive/2009/11/17/hey-scripting-guy-november-17-2009.aspx

Alternatively alternatively, you can figure out what the HTTP SOAP request needs to look like, and form it yourself within the HttpWebRequest.

jdmichal
Right. I'm not looking to use SOAP. Ideally I'd really like to simply execute get on a url in a rest-ful manner. Is this possible with WCF?
devlife
WCF exposes services via SOAP. It also has a .NET-to-.NET binary backdoor built in, to eliminate the costs of the XML conversions.http://en.wikipedia.org/wiki/Windows_Communication_Foundation#Overview
jdmichal
The huge code sample is to use this backdoor to avoid the XML conversions. Using the SOAP interface is simply better supported in PowerShell, due to the built-in New-WebServiceProxy cmdlet.
jdmichal
It looks like they have an area devoted to hosting WCF over REST. From the looks of it, you will have to modify the service to expose a REST interface. http://msdn.microsoft.com/en-us/netframework/cc950529.aspx
jdmichal
These options definitely look good. I'm not concerned with performance. I really just am looking for the easiest way to kick off a task via a wcf service via a scheduled task and would prefer not to have to create a new exe to do it (thus the powershell script).Thanks for the help!
devlife
@jdmichal: I have to say the link you provided (http://blogs.technet.com/heyscriptingguy/archive/2009/11/17/hey-scripting-guy-november-17-2009.aspx) is amazing! the WebServiceProxy class is exactly what I was looking for!
devlife
A: 

PowerShell 2.0 makes this trivial with the New-WebServiceProxy cmdlet e.g.:

$zip = New-WebServiceProxy -uri http://www.webservicex.net/uszip.asmx?WSDL
$zip.getinfobyzip(20500).table

CITY      : Washington
STATE     : DC
ZIP       : 20500
AREA_CODE : 202
TIME_ZONE : E
Keith Hill