I am trying to connect PowerShell to WCF service. I can connect to the service with a browser and with C#/.Net clients; however, when I try to connect using the PowerShell New-WebService cmdlet I get the following output:
PS Z:\> $SVC = New-WebServiceProxy -uri http://localhost:8733/Design_Time_Addresses/VIPService?Wsdl
New-WebServiceProxy : Object reference not set to an instance of an object.
At line:1 char:27
+ $SVC = New-WebServiceProxy <<<< -uri http://localhost:8733/Design_Time_Addresses/VIPService?Wsdl
+ CategoryInfo : NotSpecified: (:) [New-WebServiceProxy], NullReferenceException
+ FullyQualifiedErrorId : System.NullReferenceException,Microsoft.PowerShell.Commands.NewWebServiceProxy
Why am I getting a Null reference error?
I believe this is happening because New-WebServiceProxy only knows how to handle regular web services; it doesn't know about WCF bindings and such.
You can accomplish what you're trying to do using a client generated by svcutil.exe. Here's an example using the default WCF project that VS 2015 generates (which has a web service method called GetData which takes an int and returns a string). (This assumes your WCF service is running so that svcutil.exe can get the WSDL):
# Generate the proxy code
svcutil.exe http://localhost:55028/Service1.svc?wsdl
# Build the proxy DLL
csc /t:library .\Service1.cs
# Load the DLL
Add-Type -Path .\Service1.dll
$binding = new-object System.ServiceModel.BasicHttpBinding
$endpoint = new-object System.ServiceModel.EndpointAddress(“http://localhost:55028/Service1.svc")
# Create an instance of the client
$client = New-Object Service1Client($binding, $endpoint)
# Call a method using your client
$client.GetData(4)
svcutil.exe is using the WSDL to generate a class called Service1.cs; we can use csc.exe (or VS, if you like) to compile the class into Service1.dll and load that into PowerShell using Add-Type. I'm using the BasicHttpBinding - you'll need to look at your configuration to see what the appropriate binding is for your service. Once you've got the binding and endpoint, you can create an instance of the client and start calling methods on it.
Related
I developed a script to retrieve list items form a SharePoint Online server that works perfectly fine on my Windows 10 notebook, but not on a default Windows Server 2012 R2 instance. Here is the relevant code:
$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$context.RequestTimeout = 360000
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$list = $Context.Web.Lists.GetByTitle($ListTitle)
$qry = new-object Microsoft.SharePoint.Client.CamlQuery
$camlString = "somequery"
$qry.ViewXml = $camlString
$items = $list.GetItems($qry)
$Context.Load($items)
$Context.ExecuteQuery()
Unfortunately, the $list variable does not get any lists back from SharePoint on the 2k12 R2 server and therefore I get the following error in the end.
Exception calling "ExecuteQuery" with "0" argument(s): "Value cannot be null.
Parameter name: key"
At E:\temp\MDS_SharepointTracker_v2.ps1:131 char:5
+ $Context.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
I am pretty sure that it has something to do with the authentication, but I am not able to figure out what.
The credentials used for login are the same on both systems, both systems have the SharePoint Online Management Shell installed, Powershell version is the same and the DLLs loaded (see below). Proxy settings are the same on both systems. Through the browser, I can access SharePoint Online on the server.
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
Only difference is that I am logged in with a domain user on my notebook (although not from the same domain as the user used for SP credentials) and on the server, I am using a local user.
Anyone an idea or a hint?
After some more investigation I finally found the issue.
The server I was testing the script is not joined to a domain. Therefore, no trust is available between the server and SP online what causes the authentication to fail - although without any indication in that direction.
Examining $error[0]|format-list -force was what drove me to test on authentication issues.
Trying the script on different other clients and a domain-joined servers was successfully.
Although no more required, I couldn't find a way to be able to run the script on the workgroup server, SharePointOnlineCredentials does not seem to be able to handle login if no federation is in place...but correct me if I'm wrong
Good day all,
I am having problems adding Rest Services to mdm-admin
I had some troubles with mdm-android-* I created the service and reference in the permission.xml file
Creating a rest service in mdm-admin it has sefinitin as below
#GET
#Path("{type}/{id}/logs")
public List<? extends Application> getDeviceLogs(
#PathParam("type") String type,
#PathParam("id") String id)
throws MDMAPIException {
List<Application> applications;
ApplicationManagementProviderService appManagerConnector;
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
try {
deviceIdentifier.setType(type);
deviceIdentifier.setId(id);
appManagerConnector = MDMAPIUtils.getAppManagementService();
applications = appManagerConnector.getApplicationListForDevice(deviceIdentifier);
} catch (ApplicationManagementException e) {
String msg = "Error occurred while fetching the apps of the device.";
log.error(msg, e);
throw new MDMAPIException(msg, e);
}
return applications;
}
}
It is a clone of the get list of application method with just the path and function name changed.
When I deploy it. my webapp returns a 404 error status Code. when I try to call the function
To replicate this, Download v2.0.1 Open with Netbeans, Modify WSO2 MDM - Mobile Device Management Admin Services
Copy and paste one of the rest functions, rename the function Deploy and call that new function
How can I resolve this?
Your code snippet is working for me without any issue. You need to add permission entry in permission.xml as follows to make this work
<Permission>
<name>log device</name>
<path>/device-mgt/emm-admin/devices/logs</path>
<url>/operations/*/*/logs</url>
<method>GET</method>
</Permission>
The curl command I used is as below. don't forget to add a content type as application/json.
curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer 3c28103c1992c9e57d7091fb9f38732e" -k -v https://localhost:9443/mdm-admin/operations/android/000000000000000/logs
You are getting the 404 since you have to included the nely aded rest api permission to the user.
Please include the related permission to the one of the user's role and try that again.
Reffer to the documentation for more info.
In python, if I connect to a SOAP web service, I can do something like this to create an object using a factory function:
defdObj = WSObject.factory("ns0:MyObjectType")
In powershell, I can create a new web service, but I don't see any factory functions:
$WSObject = New-WebServiceProxy -Uri http://www.example.com/webservice?wsdl
Is it possible to create an object that is defined in a web service, using powershell?
If you call New-WebServiceProxy with a namespace, you'll be able to easily create objects that are defined in the wsdl. Here is an example:
$WSObject = New-WebServiceProxy -Uri http://www.example.com/webservice?wsdl -Namespace <MyCustomNamespaceName>
$CustomObject = New-Object <MyCustomNamespaceName>.<DefinedObjectClass>
Then $CustomObject will be the correct type, and will have the necessary functions/properties.
I created a very simple webservice in ASP.NET 2.0 to query a list in SharePoint 2007 like this:
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public string ShowSPMyList()
{
string username = this.User.Identity.Name;
return GetList();
}
private string GetList()
{
string resutl = "";
SPSite siteCollection = new SPSite("http://localhost:89");
using (SPWeb web = siteCollection.OpenWeb())
{
SPList mylist = web.Lists["MySPList"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"AssignedTo\"/><Value Type=\"Text\">Ramprasad</Value></Eq></Where>";
SPListItemCollection items = mylist.GetItems(query);
foreach (SPListItem item in items)
{
resutl = resutl + SPEncode.HtmlEncode(item["Title"].ToString());
}
}
return resutl;
}
}
}
This web service runs well when tested using the built-in server of Visual Studio 2008. The username indicates exactly my domain account (domain\myusername).
However when I create a virtual folder to host and launch this web service (still located in the same machine with SP2007), I got the following error when invoking ShowSPMyList() method, at the line to execute OpenWeb(). These are the details of the error:
System.Data.SqlClient.SqlException: Cannot open database "WSS_Content_8887ac57951146a290ca134778ddc3f8" requested by the login. The login failed.
Login failed for user 'NT AUTHORITY\NETWORK SERVICE'.
Does anyone have any idea why this error happens? Why does the web service run fine inside Visual Studio 2008, but not when running stand-alone? I checked and in both cases, the username variable has the same value (domain\myusername).
Thank you very much.
Thank you very much for the replies. I'll look into the documents to see how i can change the settings related to the application pool as suggested.
I want to make clear that i wanted to build a webservice to run outside of sharepoint (but can be deployed on the same server with sharepoint).
Is there any way i can programmatically pass the credentials (another domain account instead of 'NT AUTHORITY\NETWORK SERVICE' by default) to sharepoint when invoking OpenWeb method? I believe if i'm able to do that then i can walkaround the security issue above.
When you create your own custom virtual folder and set it inside the IIS, it's highly possible that the user account who run the application pool of that particular IIS virtual directory is currently set to NT authority\Network Service.
You can check carefully, by looking closely of what is the actual application pool that run that particular IIS virtual directory.
From there, you can go to the "Application Pool" folder and right click, choose Properties. Select the "Identity" tab, and it will show you who is the user account that currently running the application pool.
Alternatively, you can refer to the SharePoint SDK, something similar to ExtractCrmAuthenticationToken in dynamics CRM to extract the Authentication Token ticket.
Or alternatively you can use Network Credential to embed your own custom user id and password.
Hope this helps,
hadi teo
I fully agree with Hadi, if this is something you want to just quickly test, for a proof of concept, you can change the credentials under what the Application pool runs, to a user that has permissions. Or you could use Identity Impersonate setting in your config file.
However resist the temptiation to do this in a production enviroment, use the proper authentication. It will come back, to bite you.
If you need to set this up for production, there is a couple of areas that you want to look at, duplicate SPN's, and deligation probably the most common areas that is not configured correctly. Your error however points to impersanation not happening.
Also make sure you are deploying the web service to its own web site that does not already run SharePoint. If you want the web service to run on the same web site as SharePoint read Creating a Custom Web Service.
You can check what application pool identity SharePoint is using by following the same instructions that Hadi writes, but for an app pool running SharePoint. Make sure to only change the application pool used by your web service and not SharePoint or else other permission errors could occur within SP. (There should be no reason but if you are interested in changing the app pool identity used by SharePoint follow these instructions.)
On solution would be to "impersonate" as the SharePoint System account using the following code:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// also dispose SPSite
using (SPSite siteCollection = new SPSite("http://localhost:89"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
// ...
}
}
});
I learned about the basics of making a web service with Visual Studio 2008 ASP.Net + VB. And I got the "Hello World" working, but for some reason I can't get a function method to work the same way without this error, and I can't any info anywhere what to do about it.
Code:
*Web Service:*
<WebMethod()> _
Public Sub logEvent(ByVal userId As String, ByVal userGroup As String)
'method functions here
End Sub
*Mainpage Code-behind*
Protected Sub webrefTester()
Dim testi As my_dbServer.Service
testi = New my_dbServer.Service
testi.Credentials = System.Net.CredentialCache.DefaultCredentials
'have to include this because i use urls instead of local to simulate
'intended functionality, so there were authorization issues at first
testi.logEvent("userId_0", "Mgmt Services 2010")
End Sub
As said, the hello world works fine, so I have added the web reference to the solution where I need to use the web service etc etc. I just can't seem to pass parameters for the web service, it always throws a soapexception. I need that for logging info into the database.
Any other tips for a first-timer web service user would be welcome too. Basically my project has me doing a service that can be used for various software to log event information such as visitor types, possible error messages etc.
Thanks again!
It just says SoapException, this is the error message:
"Server was unable to process request. ---> Object reference not set to an instance of an object."