15 May 2017

How do I - Change a SharePoint site URL?

This is probably one of the most common questions I've been asked over the years.  Unfortunately, Microsoft doesn't provide a UI method for users to change the URL of their site.  Given the database schema and the relationships between objects and the URL, I've always been perplexed as to why this was never done.  To me it seemed like a pretty easy SQL update.

Although there are many methods to overcome this problem, such as the site backup/restore method described by Todd Klindt, these methods become increasingly more time consuming as the site size grows.  The easiest method in my mind still remains using the SPSite.Rename() method.  Unfortunately, the MSDN article states at the top that it "Changes the URL of a host-header-named site collection to a new URL.".  I believe this is why this method has remained obscure and under-leveraged.  At the end of the article, it also states "After the site rename, an app pool recycle is recommended to force refreshing the cache." which is incorrect.  An app pool recycle is required in order for the new URL to work correctly.

But enough picking apart MSDN articles... let's get to the good stuff. :-)
The following Powershell script does what we want:



The core of the script is lines 9 and 10.
Remember to recycle your web app's app pool!

Enjoy!
C

17 April 2017

How do I - Remove an item from a Powershell array.

Because Powershell is so close in syntax to C#, we often forget that it is in fact, NOT C#.  A good example of this is manipulating arrays.  While Powershell did implement the += method for adding items to an array, it does not support -= for removing them.  Fortunately, the -ne switch serves the same purpose.  See the following example for a quick demonstration of removing items from an array in Powershell.


Enjoy
C

20 March 2017

How do I - Remove duplicates from a Powershell array?

When it becomes necessary to remove duplicates from a Powershell array variable, it can quickly be achieved via the -unique switch.  You can even sort at the same time like this:


Enjoy
C

27 February 2017

How do I - Validate an Assembly is Loaded in Powershell?

Recently, I ran into an issue when auditing TFS.  The issue was related to an intermittent problem where the Powershell script would sometimes work, and sometimes fail.  From a developer perspective, this is an impossibility.  Code either works or it doesn't.  If it sometimes work, then there is most likely something else at play.
Inevitably this lead me down the path of dependencies.  I had to ensure that we had the right TFS DLLs loaded for the script.  This can easily be done with reflection via the GetAssemblies() method of the CurrentDomain within the AppDomain object in Powershell.  The simple command:

[AppDomain]::CurrentDomain.GetAssemblies()

returns a comprehensive list of loaded DLLs.  From here you can identify if your DLL is loaded, or as was the case in another session for me, identify that wrong versions of the target DLL is loaded.  That's good, but how do I use that logically in Powershell code e.g. when I want to see if a DLL is already loaded before attempting to load it again.  (As we know, that throws ugly red text that the operator might mistake for an error rather than the EXPECTED error it is.)

Therefore, using the pipe, we could do something like this:

([AppDomain]::CurrentDomain.GetAssemblies() | where {$_ -match "Microsoft.TeamFoundation.Client"}).Location -eq ""

As you can see, we pipe the output from GetAssemblies() to the where clause attempting to match with the DLL partial name, e.g. "Microsoft.TeamFoundation.Client" in this case.
By wrapping the entire statement in parentheses, we can access the .Location property of the returned object, provided there is one.  If there is none, the location value would be blank and by doing an equal check for blank, we can get a boolean result statement that identifies if a given DLL is loaded. :-)

Enjoy
C

20 February 2017

Beware of [System.Reflection.Assembly]::LoadWithPartialName!!!

If you've been in the Powershell world for any length of time, you will most certainly be familiar with this construct:

[System.Reflection.Assembly]::LoadWithPartialName(...)

This is how we quickly add DLL references to Powershell scripts without having to know the entire name of the DLL in question e.g.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint");

which loads the Microsoft.SharePoint.dll and makes all the SharePoint cmdlets available to Powershell.

BEWARE!!!  In some cases, quickly = lazy = bad.

If you are referencing a DLL that may have more than hone version on the host system, it becomes imperative that you ensure you are actually loading the right DLL.  I recently ran into this kind of thing when a script was trying to execute some TFS 2015 commands.  The script would fail however, apparently without any logical reason.
It turns out, the reason was quite logical after all.  The script was loading the "Microsoft.VisualStudio.TeamFoundation.dll" using the LoadWithPartialName() method.  Even with the TFS SDK installed, the script would load the wrong version of the DLL since the 2013 version of the exact same named DLL was in the GAC.  Since the GAC trumps everything else, the script would load the old version of the DLL from the GAC and then try to use it with newer versions of related DLLs, hence the failure to execute correctly.

If there's ever any doubt, rather use the best practice LoadFrom() method thus:

[System.Reflection.Assembly]::LoadFrom("C:\Program Files\Common Files\Microsoft Shared\web server extensions\15\ISAPI\Microsoft.SharePoint");

This way, you're 100% guaranteed the proper DLL is loaded and leveraged in your Powershell script.

Enjoy
C

16 January 2017

Quick Tip - How to migrate your Windows 7 Sticky Notes to Windows 10

With versions of Windows prior to version 10, the little Sticky Notes app that a lot of people depend on for quick notes (we really should use OneNote instead!) was easily transferred from an old computer to a new computer by simply copying the file located here:

%AppData%\Microsoft\Sticky Notes\StickyNotes.snt

to the same location on the new computer.  With Windows 10, the Sticky Notes app has graduated to the Microsoft App Store so it changed quite a bit.  Notes are no longer stored in that single .snt file and on top of that, there isn't a %AppData%\Microsoft\Sticky Notes folder anywhere to be found.
Fear not.  The solution, courtesy of Donovan Lange, an Engineering Manager for Sticky Notes, is pretty simple, though not well documented.  The following assumes a NEW computer with Windows 10.  If you simply upgrade to Windows 10, Sticky Notes will auto upgrade to the new version.
Simply follow these steps to migrate your old notes from Windows versions prior to 10, to Windows 10:
  1. Open Windows Explorer.
  2. In the address bar, paste the following without the quotes:  "%AppData%\Microsoft\Sticky Notes".
  3. Make a copy of the StickyNotes.snt file you find in this folder to transferable media such as a flash drive.
  4. On the new computer, insert the flash drive and open File Explorer.
  5. In the address bar, paste the following without the quotes: "%LOCALAPPDATA%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbw\LocalState"
  6. You will most likely NOT see a "Legacy" folder in this location.
  7. Right click > New > Folder and name the folder "Legacy" without the quotes.
  8. Double click to drill down to the Legacy folder.
  9. Now navigate to your flash drive and copy the "StickyNotes.snt" file.
  10. Navigate back to the %LOCALAPPDATA%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbw\LocalState\Legacy folder and paste the StickyNotes.snt file here.
  11. Once copied, right click on StickyNotes.snt and rename the file to "ThresholdNotes.snt" without the quotes.
  12. Close File Explorer.
  13. Close the Sticky Notes app.
  14. Restart the Sticky Notes app.
  15. You'll be presented with your old notes AND any notes you've taken in the new app.  You'll also be asked to upgrade the old notes to the new version at this point.
That's it!

Enjoy
C


 

SharePoint Remote Event Receivers are DEAD!!!

 Well, the time has finally come.  It was evident when Microsoft started pushing everyone to WebHooks, but this FAQ and related announcement...