• PowerShell, JSON, oData and CRM 2011 (or SharePoint 2010)

    I am working on how to consume data from/to SharePoint 2010 and from/to CRM 2011. I decided to try and see if I can get the data to display in PowerShell, figuring if I can get it there, I should be able to get it anywhere?  Here is the code to loop through all the Contacts in a CRM 2011 deployment.

    Took me a while to figure this out. Should work with any oData source?

    $url="http://your.crm.server/Instance/XRMServices/2011/OrganizationData.svc/ContactSet"
    $assembly = [Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
    while ($url){
    	$webclient = new-object System.Net.WebClient
    	$webclient.UseDefaultCredentials = $true
    	$webclient.Headers.Add("Accept", "application/json")
    	$webclient.Headers.Add("Content-Type", "application/json; charset=utf-8");
    	$dataString=$webclient.DownloadString($url)
    	$json=new-object System.Web.Script.Serialization.JavaScriptSerializer
    	$data=$json.DeserializeObject($dataString)
    	foreach ($result in $data.d.results){
    		write-host "$($result.FullName) , $($result.EMailAddress1)"
    	}
    	Write-Host "Press any key to continue ..."
    	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    	if ($data.d.__next){
    		$url=$data.d.__next.ToString()
    	}
    	else {
    		$url=$null
    	}
    }
    

    To loop through the items of a SharePoint 2010 list, you would change $url to:

    $url=”http://sharepoint2010.server.com/_vti_bin/listdata.svc/Announcements”

    Not sure if this would be valuable to anyone, but here it is!


  • How to tell if your PowerShell session is remote

    I wanted to write a conditional to prevent certain things from runing if in a remote PSSession.

    If you are in a standard PowerShell session the following is returned:

    [Environment]::GetCommandLineArgs()[0] = C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

    If you are in a remote PSSession:

    [Environment]::GetCommandLineArgs()[0] = C:\Windows\system32\wsmprovhost.exe 

  • How to add custom CSS code to all SharePoint 2010 pages (CustomAction)

    It occurred to me that you can add a CSS link to the top of each page using the same method that I showed in this post. The only thing you change is the code in “CustomAction”. The code would be”

    <CustomAction
      Location="ScriptLink"
      ScriptBlock="document.write('<link rel="stylesheet" type="text/css" href="/Relative/PathTo/file.css"></link>');"
      Sequence="XX" />
    

  • How to add custom JavaScript code to all SharePoint 2010 pages (CustomAction)

    There are plenty or articles on how to do this. This is more of a note for myself, as I have to “re-learn” this every time I need to customize SharePoint. There are 2 ways (that I know of) that you can add code to every page in SharePoint 2010, 1 by the AdditionalPageHead delegate control, or ,2 by Custom Action. This article is about #2 using a Custom Action. This article is about #1 – Delegate Controls

    To add JavaScript to every page via CustomAction:

    1. Start Visual Studio, and create a new Empty SharePoint Project (uncheck the Create Directory for Solution because you salways create the destination directory yourself)
    2. Deploy as a Farm Solution (I have not figured what you can and can’t do with sandboxed solutions yet)
    3. RightCLick the Project and select Add Module and name the Module at the bottom (I name the Module the name of the Document Library where I want to put the file)
    4. Delete Sample.txt and add the javascript file you want (I usually have to go to the correct folder, put the file there, right click the ProjectName and select “Show all files”, then I can include the file in the project).
    5. Chop up the elements.xml file. The final should look like this below:
      1. is changed to (Url is the Doc Library where the file will be added)
      2. is changed to (Remove the path from Url and add the “GhostableInLibrary” part)
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <Module Name="Test" Url="Test">
        <File Path="Test\jquery-1.7.min.js" Url="jquery-1.7.min.js" Type="GhostableInLibrary" />
      </Module>
    </Elements>
    

    Now you need to the code to add the file to the top of every page, add the “CustomAction” stuff below

      <CustomAction
        ScriptSrc="~SiteCollection/Test/jquery-1.7.min.js"
        Location="ScriptLink"
        Sequence="11">
      </CustomAction>
    

    Final looks like this:

    Right click the project and package it up.

    Common PowerShell commands to work with solutions are (you must create the destination Document Library before you try to install this code):

    To add/install
    Add-SPSolution H:\Path\To\wsp\Test.wsp
    Install-SPSolution Test.wsp -GACDeploy
    Update-SPSolution -literalpath  H:\Path\To\wsp\Test.wsp -identity Test.wsp -GACDeploy
    
    To remove
    Uninstall-SPSolution Test.wsp
    Remove-SPSolution Test.wsp
    

    This results in a new Feature in manage features (Active it!)

    A new file in the document library, and the following in the source code for the page. Done!:


  • How to use Visual Studio to package a SharePoint solution if you don’t have SharePoint installed

    I re-image my machine often, and when I fire up a Visual Studio 2010 for the first time, I always get an error “To work with this project, either SharePoint Foundation 2010 or SharePoint Server 2010 must be installed on the system” or “A SharePoint server is not installed on this computer. A SharePoint server must be installed to work with SharePoint projects.”

    Instead of installing SharePoint on my local machine, I usually just trick Visual Studio into thinking that SharePoint is installed. This link says to export the RegHive from a real SharePoint server and import it. I can never remember this.

    To compile your code, you need to copy the “Microsoft.SharePoint.dll” and Microsoft.SharePoint.Security.dll from “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI” to your local drive and “Add Reference” to your project (Right Click References)

    Haven’t worked with remote debugging to much, but this article describes it.


  • How to tell if your PowerShell function was called by name or by alias

    I been wanting to write functions that act differently depending on how they were called. I am not sure if this is good practice or not, but I like the idea. Turns out all you need is “$MyInvocation.InvocationName” Look at they following code:

    Function Test-Calling {
    if ($MyInvocation.InvocationName -eq "cows"){Write-host "This function was called by an alias ($($MyInvocation.InvocationName))"}
    if ($MyInvocation.InvocationName -eq $MyInvocation.MyCommand){Write-host "This function was called by name ($($MyInvocation.MyCommand))"}
    }
    set-alias cows Test-Calling
    

    If you call the function by alias you get : This function was called by an alias (cows)
    If you call the function by it’s name you get: This function was called by name (Test-Calling)

    I hope that helps someone.

    
    

  • 3000 Visitors on one month!

    I remember thinking, when I hit 2000 visitors in a month, I will never make 3000!


  • PowerShell script to force download and install WindowsUpdates

    I have been using the UpdateHF.vbs vbscript for years to patch all my servers. I wrote a simple HTA to wrap it, and it gets executed by psexec. I wanted to take that script, strip it down, and convert it to PowerShell. My intension was to  run it through a PSSession but I get access denied. Maybe I will try launching it with SCCM?

    I found these three scripts, that I chopped to together for a script that I wanted:

    Function JBMURPHY-Install-WindowsUpdates {
    PARAM([switch]$Install,[switch]$reboot)
    	if($(Test-Path &quot;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired&quot;)){
    		if (!($reboot)){
        		write-host &quot;There are pending reboots, please pass the reboot command&quot;
        		return
    		}
    		else{
    		restart-computer
    		return
    		}
    	}
    
    	Write-Host -nonewline &quot; + Searching for Updates: &quot;
    	$UpdateSession = New-Object -ComObject Microsoft.Update.Session
    	$Updates=$updateSession.CreateupdateSearcher().Search(&quot;IsAssigned=1 and IsHidden=0 and IsInstalled=0&quot;).Updates
    	Write-Host &quot; Found [$($Updates.count)] Updates to Download and install`n`n&quot;
    
    	$UpdatesCollection = New-Object -ComObject Microsoft.Update.UpdateColl
    	$UpdatesDownloader = $UpdateSession.CreateUpdateDownloader()
    	foreach ($Update in $Updates){
    
    		# Add Update to Collection
    		if ( $Update.EulaAccepted -eq 0 ) { $Update.AcceptEula() }
    		$UpdatesCollection.Add($Update) | out-null
    
    		# Download
    		Write-Host -NoNewline &quot; + Downloading Update $($Update.Title)&quot;
    		$UpdatesDownloader.Updates = $UpdatesCollection
    		$DownloadResult = $UpdatesDownloader.Download()
    		$DownloadResultResultCode = switch -exact ($DownloadResult.ResultCode)
    		{
    		  0   {&quot;NotStarted&quot;}
    		  1   {&quot;InProgress&quot;}
    		  2   {&quot;Succeeded&quot;}
    		  3   {&quot;SucceededWithErrors&quot;}
    		  4   {&quot;Failed&quot;}
    		  5   {&quot;Aborted&quot;}
    		}
    		$Message = &quot; [{0}] &quot; -f ($DownloadResultResultCode)
    		Write-Host -ForegroundColor Green $message
    	}
    	if (($Install) -and ($($Updates.count) -gt 0)) {
    	write-host &quot;`n`nInstalling updates&quot;
    	$Installer = $UpdateSession.CreateUpdateInstaller()
    	$Installer.Updates = $UpdatesCollection
    	$InstallerResult = $Installer.Install()
    	$InstallerResultCode = switch -exact ($InstallerResult.ResultCode)
    		{
    		  0   {&quot;NotStarted&quot;}
    		  1   {&quot;InProgress&quot;}
    		  2   {&quot;Succeeded&quot;}
    		  3   {&quot;SucceededWithErrors&quot;}
    		  4   {&quot;Failed&quot;}
    		  5   {&quot;Aborted&quot;}
    		}
    		$Message = &quot; Installation [{0}] &quot; -f ($InstallerResultCode)
    		Write-Host $message
    		Write-Host
    	}
    	if (($reboot) -and ($($Updates.count) -gt 0)) {
    	if($(Test-Path &quot;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired&quot;))
    		{
        		write-host &quot;Rebooting&quot;
        		restart-computer
    		}
    	}
    }
    

    Thanks to those that put the original scripts together