我有一个计划任务,每小时执行一次powershell脚本。 powershell脚本必须调用单向WCF服务操作。基本上它只需要启动一个操作。我的问题是我该怎么做呢?我认为只是执行url实际上会启动请求,但显然这是不正确的。
这是我想要做的事情:
$request = [System.Net.WebRequest]::Create("http://myserver.com/myservice/dosomething")
$request.GetResponse()
该操作不接受任何参数并返回void。
答案 0 :(得分:8)
PowerShell 2.0使用New-WebServiceProxy cmdlet实现这一点:例如:
$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
答案 1 :(得分:7)
我认为问题在于您拥有的代码实际上是在创建HttpWebRequest,而不是WCF请求。 (换句话说,它只是在URL上执行HTTP GET请求,没有SOAP或.NET Remoting信息。)
您应该能够按照这些说明创建合适的端点:
http://msdn.microsoft.com/en-us/magazine/cc163647.aspx#S11
看起来应该是这样的:
$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();
请注意,您需要导入带有IYourInterface
类的DLL才能生效:
[void] [Reflection.Assembly]::LoadFrom('path/to/your.dll')
或者,如果您为服务定义了WSDL,则可以按照这些更简单的说明访问该服务:
http://blogs.technet.com/heyscriptingguy/archive/2009/11/17/hey-scripting-guy-november-17-2009.aspx
或者,您可以确定HTTP SOAP请求的外观,并在HttpWebRequest
内自行构建。
答案 2 :(得分:0)
我相信在尝试获取响应之前,您需要先设置HTTP方法。默认情况下,我认为 WebRequest 对象默认为 POST ,但您实际上需要将其设置为 GET 。
我没有多少使用PowerShell脚本,但根据您的示例,它看起来像这样:
$request = [System.Net.WebRequest]::Create("http://myserver.com/myservice/dosomething")
$request.Method = "GET"
$request.GetResponse()
希望有所帮助!
答案 3 :(得分:0)
HTTP重播方法:
您不必使用WCF来调用WCF服务,您可以使用HTTP默认值进行3-4次更改来模仿。只是不要尝试自己构建SOAP信封。但是,通过“普通”HTTP重播Fiddler所需的一切是安全的。
答案 4 :(得分:0)
我喜欢jdmichal的答案,因为直接使它适用于参数为对象的输入......代码需要进行一些修改,这对我有用:
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Critical, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "C:\Logs\MyCriticalTraces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
更新: 我已经了解了如何将复合对象与New-WebServiceProxy cmdlet一起使用(感谢http://www.sqlmusings.com/2012/02/04/resolving-ssrs-and-powershell-new-webserviceproxy-namespace-issue/)
[Reflection.Assembly]::LoadFrom("C:\.....\WcfService2.dll")
[Reflection.Assembly]::LoadWithPartialName("System.ServiceModel")
$httpBinding = New-Object System.ServiceModel.BasicHttpBinding
if($useNTLM){
#passes the default creds
$httpBinding.Security.Mode = "TransportCredentialOnly"
$httpBinding.Security.Transport.ClientCredentialType = "Ntlm"
}
$endpointAddress = New-Object System.ServiceModel.EndpointAddress 'http://localhost:63600/Service1.svc'
$contractDescription = [System.ServiceModel.Description.ContractDescription]::GetContract([WcfService2.IService1])
$serviceEndpoint = New-Object System.ServiceModel.Description.ServiceEndpoint($contractDescription, $httpBinding, $endpointAddress)
$channelFactory = New-Object "System.ServiceModel.ChannelFactory``1[WcfService2.IService1]"($serviceEndpoint)
$webProxy = $channelFactory.CreateChannel();
$result = $webProxy.GetData(123);
Write-Output $result #prints 123
$comptype = new-object WcfService2.CompositeType
$comptype.BoolValue =$false
$comptype.StringValue = "whatever123zxcv"
$result = $webProxy.GetDataUsingDataContract($comptype);
Write-Output $result #prints whatever123zxcv