Powershell Webservice Method definition changes - web-services

I am using powershell to deploy our SSRS reports, but have come across an issue when deploying multiple reports.
$uri = "http:///Reportserver2008/reportservice2005.asmx"
$Proxy = New-WebServiceProxy -Uri $uri -Namespace SSRS.ReportingService2005 -UseDefaultCredential ;
$Proxy | gm "SetItemDataSources"
Which returns a method definition of:
System.Void SetItemDataSources(string Item, SSRS.ReportingService2005.DataSource[] DataSources)
If I duplicate the code above, the method definition changes the second time it is requested
e.g
$uri = "http:///Reportserver2008/reportservice2005.asmx"
$Proxy = New-WebServiceProxy -Uri $uri -Namespace SSRS.ReportingService2005 -UseDefaultCredential ;
$Proxy | gm "SetItemDataSources"
$Proxy = New-WebServiceProxy -Uri $uri -Namespace SSRS.ReportingService2005 -UseDefaultCredential ;
$Proxy | gm "SetItemDataSources"
Returns two different method definitions:
System.Void SetItemDataSources(string Item, SSRS.ReportingService2005.DataSource[] DataSources)
System.Void SetItemDataSources(string Item, SSRS.ReportingService2005.DataSource[], 0juuvurk, Ve...
Can anyone explain why the definition changes???
I have tried disposing $proxy after first request, Uri does not change
I am thinking I may have to pull out $proxy and only assign it once.
Any insight greatly appreciated!

You're right on with your instincts. Creating 2nd or 3rd proxies of web services can cause trouble, because the proxies get put into automatically generated namespaces. So proxying twice actually redoes a lot of work, and creates two very similar looking types in memory.
There are generally two ways to work with this sort of issue:
Use the -Namespace parameter to force the object into a namespace.
Use $proxy.GetType().Namespace to find the automatically generated base type
Hope this helps

Related

Nginx regular expression on map

Not an expert on regexs,
working on a nginx project, and we are looking for a way to map the first two (2) directories levels of a uri
map $uri $my_uri {
~^(?<base_uri>.*)/[^/]+$ $base_uri;
default $uri;
}
So far this code return the base_uri without the domain/server or any filenames
But I need this original request :
http://example.com/level1/level2/file.ext
http://example.com/level1/level2/level3/file.ext
http://example.com/level1/level2/level3/level4/[...more levels...]/file.ext
to return only the first 2 levels, regex should return
/level1/level2
Please note:
sub-folders (lavel1, lavel2) will be dynamic folder names, not static.
nginx's $url variable does not include protocol/server/port from the original request. so regex is performed against /level1/level2/level3/[...]/file.ext
any help will be appreciated.

Powershell consuming webservice - missing return value

Consuming a simple webservice using powershell. It is supposed to return 2 values, but powershell only shows one. SOAPUI works fine, shows two values. If I don't pass as [ref] the call errors. Not sure why this is?
$URL = "https://nonpublic/wsdl/location"
$URI = New-Object System.Uri($URL);
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$webproxy = New-WebServiceProxy -Uri $URI -Namespace webproxy-class ssl
## webservice to return two values related to passed value
$val = "ide-550"
$result = $webproxy.getinfo([ref]$val)
$result ## <-- only one value
EDIT: get member output - statustype getinfo(string [ref] val).

RegEx Finding multiple matches with a quantifier

I have this PowerShell code:
$uri = "http://charts.spotify.com/api/tracks/most_streamed/au/daily/latest"
$ContentType = "application/json"
$postblog = (Invoke-WebRequest -Uri $uri).Content -match 'track_name\S:\S(.*?)",'
$matches[1]
When I run this, I get this result:
FourFiveSeconds
Problem is, I know there are more songs than just this one song. And I know that the match I am using, the string of text "track_name" exists more than once. How can I change my RegEx so that it matches every match it can find? In other words, the expected output would be multiple matches, allowing me to list all the songs, e.g. $matches[1], $matches[2], $matches[3], $matches[4], etc.
Since you are using Invoke-WebRequest, I assume you are using Powershell v4.0. Therefore, you can use ConvertFrom-Json on the data received and iterate over it, instead of using a regex solution:
$uri = "http://charts.spotify.com/api/tracks/most_streamed/au/daily/latest"
$ContentType = "application/json"
$postblog = (Invoke-WebRequest -Uri $uri).Content | ConvertFrom-Json
Now, the entire tracks data is available inside $postblog.tracks array.
Iterate over them to get the track_urls:
Foreach( $track in $postblog.tracks ) {
Write-Output $track.track_url
}
EDIT
Apparently, you can simply use:
Write-Output $postblog.tracks.track_url
instead of the Foreach code-block. Thanks to #PetSerAl for that :)
Thanks to all, yes you are right, converting it to JSON gives me heaps more options and it is cleaner than using RegEx.
I have this script now, which should definitely do the trick.
$spotifytopsongs = #()
$uri = "http://charts.spotify.com/api/tracks/most_streamed/au/daily/latest"
$ContentType = "application/json"
$spotifyjson = (Invoke-WebRequest -Uri $uri).Content | ConvertFrom-Json
$spotifyjson.tracks | select -First 50 | % {$spotifytopsongs += #($_.artist_name + " - " + $_.track_name)}
cls;$spotifytopsongs

SoapClient does not recognize a function I am seeing in WSDL

I have a simple webservice in symfony2 that is working perfectly. I have added a new method, however, strangely, that method is not recognized, even when I see it in the WSDL definition.
Please load: WSDL definition
Method is called GetHoliday
The controller that executes that method is the following:
public function getHolidayAction() {
date_default_timezone_set('America/Santiago');
$request = $this->getRequest();
$client = new \SoapClient('http://' . $request->getHttpHost() . $request->getScriptName() . '/feriados?wsdl');
$year = $request->get('year');
$month = $request->get('month');
$day = $request->get('day');
$types = $client->__getFunctions();
var_dump($types);
die();
$result = $client->GetHoliday('8cd4c502f69b5606a8bef291deaac1ba83bb7727', 'cl', $year, $month, $day);
echo $result;
die();
}
After the call to __getFunctions call, GetHoliday method is missing.
If you want to see the __getFunctions response, please load online site
Enter any date in the input field. The response will appear in red.
The most curious thing, is that this works in my development machine which also has RedHat operating system (my hosting is HostGator).
Any help will be appreciated,
Finally, the problem was that the WSDL was being cached.
To make the first test, I used
$client = new \SoapClient('http://' . $request->getHttpHost() . $request->getScriptName() . '/feriados?wsdl', array('cache_wsdl' => WSDL_CACHE_NONE) );
To instantiate SoapClient. That way, it worked. so to get rid of WSDL_CACHE_NONE parameter, I deleted all files that start with wsdl in /tmp folder.
Regards,
Jaime

Powershell, web services and object types

I'm new to using web services under powershell, so maybe I have a basic misunderstanding about something. I'm working with Microsoft's Reporting Services. Here is a repro script.
$computer = "rptdev"
$uri = "http://$($computer)/ReportServer/ReportService.asmx?WSDL"
$reporting = New-WebServiceProxy -uri $uri -UseDefaultCredential -namespace "ReportingWebService"
$dsRef = new-object ReportingWebService.DataSourceReference
$ds = new-object ReportingWebService.DataSource
$dsRef.GetType()
$ds.GetType()
If I run that, I get something that looks more or less like this:
Name BaseType
---- --------
DataSourceReference ReportingWebService.DataSourceDefinitionOrReference
DataSource System.Object
So, my question is: Why does DataSource have System.Object as a BaseType when DataSourceReference clearly has a object type that is based on the web object? They were both created from the ReportingWebService namespace, weren't they?
My root problem is that I need to hand an array of DataSources back to SetItemDataSources, and SetItemDataSources chokes on an array of System.Objects, and I don't seem to be able to cast it to what I want.
All this means is that the "DataSource" class inherits directly from System.Object. Whereas "DataSourceReference" inherits from "DataSourceDefinitionOrReference", then maybe something else, then System.Object.
However, I do not think that is your problem. Your problem is probably PowerShell's automatic splitting and recombining of collections as generic collections of System.Object. You can control this by setting a static type on the collection like so (I'm guessing on this API you are using since I haven't used it myself):
$computer = "rptdev"
$uri = "http://$($computer)/ReportServer/ReportService.asmx?WSDL"
$reporting = New-WebServiceProxy -uri $uri -UseDefaultCredential -namespace "ReportingWebService"
[ReportingWebService.DataSource[]]$DataSources = <do something to get your data sources>
$reporting.SetItemDataSources($DataSources)
If you only have a single object and you want to pass an array of objects (i.e. an array with a single element in it - your sole object), you use the #() syntax:
ps> $o = new-object mynamespace.myobj
ps> $thing.Method( #($o) )
-Oisin