• Using PowerShell to query CRM 2011 SOAP endpoint – help!

    I don’t know what I am doing wrong. All I am trying to do is to query  CRM 2011 via PowerShell and SOAP. The following PowerShell script should return the Contact’s full name, but I get nothing. Any ideas??

    Here is the PowerShell:

    $xml = "<?xml version='1.0' encoding='utf-8'?>"
    $xml += "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"
    $xml += "<soap:Body>"
    $xml += "<Retrieve xmlns='http://schemas.microsoft.com/xrm/2011/Contracts/Services'>"
    $xml += "<entityName>contact</entityName>"
    $xml += "<id>12345678-1234-1234-1234-123456789012</id>"
    $xml += "<columnSet xmlns:q1='http://schemas.microsoft.com/xrm/2011/Contracts' xsi:type='q1:ColumnSet'>"
    $xml += "<q1:Attributes>"
    $xml += "<q1:Attribute>fullname</q1:Attribute>"
    $xml += "<q1:Attribute>telephone1</q1:Attribute>"
    $xml += "</q1:Attributes>"
    $xml += "</columnSet>"
    $xml += "</Retrieve></soap:Body></soap:Envelope>"
    
    $url="http://crmserver.company.com/Organization/XRMServices/2011/Organization.svc/web"
    $http_request = New-Object -ComObject Msxml2.XMLHTTP
    $http_request.Open('POST', $url, $false)
    $http_request.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Retrieve");
    $http_request.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    $http_request.setRequestHeader("Content-Length", $xml.length);
    $http_request.send($xml);
    $http_request.responseText
    

    And here is the response:

    $http_request.responseText
    
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body><RetrieveResponse xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
    <RetrieveResult xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <a:Attributes xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
    <a:KeyValuePairOfstringanyType>
    <b:key>accountid</b:key>
    <b:value i:type="c:guid" xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/">12345678-1234-1234-1234-123456789012</b:value>
    </a:KeyValuePairOfstringanyType>
    </a:Attributes>
    <a:EntityState i:nil="true"/><a:FormattedValues xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
    <a:Id>12345678-1234-1234-1234-123456789012</a:Id><a:LogicalName>account</a:LogicalName>
    <a:RelatedEntities xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
    </RetrieveResult>
    </RetrieveResponse>
    

    I just don’t know what I am doing wrong. Why won’t the code return “fullname”, it is in the columnSet.

    Update-2012-05-08:I have posted my question here, no answer yet

    Update2-2012-05-05: I have posted and received and answer here on stack overflow. Big thanks to @JLattimer


  • How to get the count of items returned in jQuery Autocomplete

    In this post I used jQuery to autocomplete an input box with results from CRM 2011. I wanted to give the number of results returned for the particular autocomplete query. I chose to use the autocomplete open: parameter to get the number of results returned, and I put that result in a div with an ID of “Count”

     

    open: function(event,ui){
    	    var len = $(this).autocomplete("widget").find( "li" ).length;
    	    var resultText='RESULTS';
    	    if (len==1) resultText='RESULT'
    	    $('#Count').text('FOUND '+len+' '+resultText);
    	  	},
    close: function(event,ui){
    	    $('#Count').text('ENTERPRISE SEARCH');
      	}
    
    

  • PowerShell script to copy a SharePoint Document Library to a Local Path

    I wanted to have a PowerShell script that downloaded A Document Library’s contents to a local folder. This is what I put together.

    Function JBM-SharePoint-CopyDocumentLibraryLocal {
    PARAM([Parameter(Mandatory=$true)]$SiteURL,
        [Parameter(Mandatory=$true)]$DocumentLibrary,
        [Parameter(Mandatory=$true)]$Destination)
    $spWeb = Get-SPWeb -Identity http://$SiteURL
    $list = $spWeb.Lists[$DocumentLibrary]
    foreach ($listItem in $list.Items)
    {
        $DestinationPath = $listItem.Url.replace("$DocumentLibrary","$Destination").Replace("/","\")
        write-host "Downloading $($listItem.Name) -> $DestinationPath"
    
        if (!(Test-Path -path $(Split-Path $DestinationPath -parent)))
        {
            write-host "Createing $(Split-Path $DestinationPath -parent)"
            $dest = New-Item $(Split-Path $DestinationPath -parent) -type directory
        }
        $binary=$spWeb.GetFile($listItem.Url).OpenBinary()
        $stream = New-Object System.IO.FileStream($DestinationPath), Create
        $writer = New-Object System.IO.BinaryWriter($stream)
        $writer.write($binary)
        $writer.Close()
    }
    $spWeb.Dispose()
    

  • Update DynDNS from the command line

    My router is not updating DynDNS correctly, so I wanted to use a simple cron job to do the same. Here is a simple BASH/Shell script to update DynDNS:

    IP=$(curl -s icanhazip.com)
    curl -v -k -u username:password “https://members.dyndns.org/nic/update?hostname=DNSHOSTNAME.dyndns.org&myip=$IP”


  • SharePoint 2010, Client OM, jQuery Autocomplete and BCS/External lists

    In this previous post, I used jQuery/SOAP/SPServices to access a SharePoint BCS list (an external list). I wanted to do the same thing using the Client Object Model (Some call it Clien OM? Or maybe CSOM?). Below is the code to access contact data in a BCS connection to Microsoft CRM 2011, and use it for autocomplete values. Things to note:

    1. You need to have a method tag in your CAML statement. This tells the list which “Operation” (as it is listed in SharePoint Designer) to use
    2. You need to use the “include method” with the executeQueryAsync method
    3. You need to include the ViewFields tags in the CAML statement, and I think they should match the include statement above
    $('#ContactsSearchTextbox').autocomplete({
        source: function( request, response ) {
    	    var CAMLQuery= "<View><Method Name='ContactReadList' /><Query><Where><Contains><FieldRef Name='FullName' /><Value Type='Text'>"+request.term+"</Value></Contains></Where></Query><ViewFields><FieldRef Name='FullName' /><FieldRef Name='ContactId' /><FieldRef Name='ParentCustomerIdName' /></ViewFields></View>";
    		var context = new SP.ClientContext.get_current();
    		var web = context.get_web();
    		var list = web.get_lists().getByTitle('Contacts');
    		var query = new SP.CamlQuery;
    		query.set_viewXml(CAMLQuery);
    		allItems = list.getItems(query);
    		context.load(allItems, 'Include(FullName,ContactId,ParentCustomerIdName)');
    		context.executeQueryAsync(function (){
    			var arrayOfResults = new Array();
    			var listItemEnumerator = allItems.getEnumerator(); 
    			while(listItemEnumerator.moveNext()) {
    				var oListItem = listItemEnumerator.get_current();
    				arrayOfResults.push(oListItem);
    			}
    			response($.map(arrayOfResults ,function( item ) {
    				return {
    				label: item.get_item('FullName') + ' (' + item.get_item('ParentCustomerIdName') + ')',
    				value: item.get_item('ContactId'),
    				id: item.get_item('FullName')
    				}
    			}));
    		},function(sender, args){
    		   alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
    		});        
    	},
    	minLength: 5,
    });
    

  • Accessing SharePoint 2010 BCS lists via SOAP/WebServices for use in a jQuery autocomplete

    So it seems that you can’t access BCS list data via REST, according to this article. But it seems that you can access the list data through SOAP. I used the code below to query a BCS list that points to a MSCRM 2011 backend (I know I could go right to CRM via REST, but then I would have XSS issues). I then take the results and use them for a jQuery autocomplete for an input box. Obviously in the code below, Contacts is a BCS “external List”

     

    
    $('#ContactSearchTextbox').autocomplete({
    source: function( request, response ) {
    	$().SPServices({
    	operation: "GetListItems",
    	async: false,
    	listName: "Contacts",
    	CAMLViewFields: "<ViewFields><FieldRef Name='FullName' /><FieldRef Name='ContactId' /><FieldRef Name='ParentCustomerIdName' /></ViewFields>",
    	CAMLQuery: "<Query><Where><Contains><FieldRef Name='FullName' /><Value Type='Text'>"+request.term+"</Value></Contains></Where></Query>",
    	completefunc: function (xData, Status) {
    	$('#SearchResults').html(xData.responseText);
    	response($.map( $(xData.responseXML).SPFilterNode("z:row"), function( item ) {
    	return {
    	label: $(item).attr('ows_FullName') + "(" + $(item).attr('ows_ParentCustomerIdName') +")",
    	value: $(item).attr('ows_ContactId')
    		}
    	}));
    	}
    	});	    
    },
    minLength: 4
    });
    

  • Add an appointment/email/phone activity to CRM 2011 via PowerShell (REST/oDATA)

    I am looking to move some older list data into CRM 2011, so I wanted a way to create some “activities” via powershell. Below is the code to do that. In the first part of the code, I create a PowerShell object and then I convert it to a JSON object via PowerShell 3’s new ConvertTo-JSON cmdlet.

    $JsonObject = New-Object psobject -Property @{
    ActivityTypeCode = "appointment"
    Subject = "jbmurphy TEST"
    Description = "This is a descritpion"
    ScheduledStart = "2012-03-20T18:00:00Z"
    ScheduledEnd = "2012-03-20T18:00:00Z"
    Location = "Office"
    }
    
    # I am using PowerShell 3's ConvertTo-Json
    $jsonEntity=$JsonObject | ConvertTo-Json
    #$url="http://crmserver.company.com/OrgName/xrmservices/2011/OrganizationData.svc/EmailSet"
    #$url="http://crmserver.company.com/OrgName/xrmservices/2011/OrganizationData.svc/PhoneCallSet"
    $url="http://crmserver.company.com/OrgName/xrmservices/2011/OrganizationData.svc/AppointmentSet"
    
    $http_request = New-Object -ComObject Msxml2.XMLHTTP
    $http_request.open('POST', $url, $false)
    $http_request.setRequestHeader("Accept", "application/json")
    $http_request.setRequestHeader("Content-Type", "application/json; charset=utf-8")
    $http_request.send($jsonEntity)
    $http_request.statusText
    

  • PowerShell script to search SharePoint Search WebService via SOAP

    I wanted to copy all the files found in a SharePoint Search result for a scope that lived on a file share. So I wrote the following PowerShell code to query a SharePoint Search scope and find the url for each result.

    #$KeywordQuery="Cows"
    $SQLQuery="SELECT WorkId,Path,Title,Write,Author from Scope() WHERE `"Scope`"='NarrowScope' AND FREETEXT(defaultproperties,'Cows')"
    
    $CountToReturn = 1000
    $xmlDoc = new-object System.Xml.XmlDocument
    $QueryPacket = $xmlDoc.CreateElement("QueryPacket")
    $QueryPacket.SetAttribute("xmlns", "urn:Microsoft.Search.Query")
    $Query = $xmlDoc.CreateElement("Query")
    [void]$querypacket.AppendChild($Query)
    $Context = $xmlDoc.CreateElement("Context")
    [void]$query.AppendChild($Context)
    $QueryText = $xmlDoc.CreateElement("QueryText")
    
    #If you are Using the KeyWord method
    #$QueryText.SetAttribute("type", "string") 
    #$QueryText.set_InnerXMl($KeywordQuery)
    
    #IF you are using SQL method
    $QueryText.SetAttribute("type", "MSSQLFT")
    $QueryText.set_InnerXMl($SQLQuery)
    
    [void]$context.AppendChild($QueryText)
    $Range = $xmlDoc.CreateElement("Range")
    [void]$query.AppendChild($Range)
    $Count = $xmlDoc.CreateElement("Count")
    $Count.set_InnerXMl($CountToReturn)
    [void]$range.AppendChild($Count)
    
    $IncludeSpecialTermResults=$xmlDoc.CreateElement("IncludeSpecialTermResults")
    $IncludeSpecialTermResults.set_InnerXML("false")
    [void]$query.AppendChild($IncludeSpecialTermResults)
    
    $PreQuerySuggestions=$xmlDoc.CreateElement("PreQuerySuggestions")
    $PreQuerySuggestions.set_InnerXML("false")
    [void]$query.AppendChild($PreQuerySuggestions)
    
    $HighlightQuerySuggestions=$xmlDoc.CreateElement("HighlightQuerySuggestions")
    $HighlightQuerySuggestions.set_InnerXML("false")
    [void]$query.AppendChild($HighlightQuerySuggestions)
    
    $IncludeRelevantResults=$xmlDoc.CreateElement("IncludeRelevantResults")
    $IncludeRelevantResults.set_InnerXML("false")
    [void]$query.AppendChild($IncludeRelevantResults)
    
    $IncludeHighConfidenceResults=$xmlDoc.CreateElement("IncludeHighConfidenceResults")
    $IncludeHighConfidenceResults.set_InnerXML("false")
    [void]$query.AppendChild($IncludeHighConfidenceResults)
    
    $Service = New-WebServiceProxy -UseDefaultCredential -uri http://sharepoint.search.com/Search/_vti_bin/Search.asmx
    [ xml ]$Results = $Service.Query($QueryPacket.OuterXml)
    write-host "Results=$($Results.ResponsePacket.Response.Range.Count)"
    foreach ($Doc in $Results.ResponsePacket.Response.Range.Results.Document){
    $PATH=$($Doc.Action.LinkUrl.("#text")).Replace("/","\").Replace("file:","")
    write-host $PATH
    #here is where you put your copy cmd
    cp $PATH c:\Temp
    }