<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>RCormier's SharePoint Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/rcormier/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/rcormier/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 14 Mar 2018 19:22:33 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>How-to: For-each for Hash Tables in PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/how-to-for-each-for-hash-tables-in-powershell</link>
      <pubDate>Wed, 14 Mar 2018 18:23:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/?p=705</guid>
      <description><![CDATA[Have you ever encountered a situation where you may need a dynamic array – perhaps because you’re...]]></description>
      <content:encoded><![CDATA[<p>Have you ever encountered a situation where you may need a dynamic array – perhaps because you’re working with an undetermined number of objects, or collections of objects that don’t all look the same or aren’t the same type?&nbsp; When this happens to me, I typically switch gears and use a hash table.</p><p>This can be done quite easily by using the following PowerShell syntax:</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Declare-Hashtable.jpg"></p><p>Next, I’ll just go and populate the hash table with a few simple values</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/image157.png"></p><p>Now, we can check the value of $HashTable, and we should return something like this</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Return-Hashtable1.jpg"></p><p>Now for the fun part.&nbsp; Since we’re all used to working with arrays, and the HashTable kind of looks and feels like an array (it’s not an array), it’s pretty natural for us to think: “Hey, I’ll just go grab the first item in the array by using $HashTable[0].&nbsp; This is what you’ll get if you do that</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Hashtable-0.jpg"></p><p>If we want to reference a specific item in a Hash Table, we have to reference the key.&nbsp; How do we get the key, you might ask?&nbsp; like this</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Hashtable-Keys.jpg"></p><p>So, if I want to return the value of the item in the Hash Table with the key named “GitHubProcesses”, I would do this</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Hashtable-GitHub.jpg"></p><p>So, what does that have to do with for-each&nbsp; for Hash Tables?&nbsp; Simple.&nbsp; We can get a list of keys, and we need those keys if we want to get values.&nbsp; So you can simply iterate through all keys in the Hash Table and get the value of each key, like this</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Write-host-HashTable.jpg"></p><p>And that would produce an output like this</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/image163.png"></p><p>So the next question would be: what happened to that nice task list that I had before?&nbsp; And that all comes down to knowing the type of data you’re working with.&nbsp; In that case, we have stored an array into the value of the GitHubProcesses key, and we have stored a string into the value of the Roger key.&nbsp; We can verify this pretty easily</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/image164.png"></p><p>This will produce the following output</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/image165.png"></p><p>So, knowing the type of data you are working with is also important.&nbsp; In the previous case, the array was being output as an array of entries, as opposed to the value of those entries, whereas the string was cleanly being displayed as the value of the string.&nbsp; We could have simply chosen not to use write-host, so that the array would be expanded, like so</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/HashTable-Keys-Script.jpg"></p><p>This would provide the following output</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/HashTable-Keys-Output.jpg"></p><h1></h1><h1>Summary</h1><p>Long story short, the key, literally, is the key to working with Hash Tables..&nbsp; Once you’ve mastered that, you can then start implementing advanced logic, such as detecting the object type, or well, anything other than simply outputting the value to the console.</p><p><img src="https://msdnshared.blob.core.windows.net/media/2018/03/HashTable-Your-Logic.jpg"></p><h1></h1><h1>Feedback</h1><p>As always, should you have any feedback, feel free to post in the comments below.</p><p>You can also reach me on twitter <a href="https://twitter.com/RCormier_MSFT" target="_blank">@RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>SharePoint Online and CSOM: A quick reminder to read error messages properly!</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/sharepoint-online-and-csom-a-quick-lesson-in-poor-error-messages</link>
      <pubDate>Tue, 20 Dec 2016 16:13:49 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/?p=365</guid>
      <description><![CDATA[&nbsp; This blog post is going to describe what I found to be a pretty confusing error message, that...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p> <p>This blog post is going to describe what I found to be a pretty confusing error message, that you might also encounter when trying to manage SharePoint Online sites with CSOM in PowerShell.</p> <p>&nbsp;</p> <h1>Background</h1> <p>I had encountered this issue while creating a script for a client that would standardize site collection audit settings across all personal sites, so that users would be able to have direct access to audit data for their OneDrive for Business libraries, without having to open a ticket so that somebody with access to the Security and Compliance center can provide them with the requested data.</p> <p>&nbsp;</p> <h1>Approach</h1> <p>The first thing I did was make sure that I had the <a href="https://www.microsoft.com/en-us/download/details.aspx?id=42038" target="_blank">SharePoint Online Client Component SDK</a> installed.&nbsp; This would make sure that the appropriate assemblies are installed on my system and registered in the GAC.&nbsp; There are other ways to get access to the assemblies, but this is my preferred method.</p> <p>The next thing I did was launch PowerShell ISE as Administrator and load the assemblies that I wanted to use in this particular script</p> <blockquote> <p>[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")<br>[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")</p></blockquote> <p>Next, I defined all of the variables that I was going to use, such as the Site URL, and the credentials to be used, etc. before finally trying to create the necessary context</p> <blockquote> <p>$ClientContext = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)</p></blockquote> <p>This resulted in an error message that appeared very helpful at first</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/Constructor.jpg" target="_blank"><img src="https://msdnshared.blob.core.windows.net/media/2016/12/Constructor.jpg"></a></p> <blockquote> <p>New-Object : A constructor was not found. Cannot find an appropriate constructor for type Microsoft.SharePoint.Client.ClientContext.<br>At line:1 char:18<br>+ ... ntContext = New-Object Microsoft.SharePoint.Client.ClientContext($Sit ...<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ObjectNotFound: (:) [New-Object], PSArgumentException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand</p> <p>&nbsp;</p></blockquote> <p>I was very certain that I had loaded all of the necessary assemblies.&nbsp; First I checked over some of my previous similar scripts –&nbsp; they had no problem creating the context when only these two assemblies were loaded.</p> <p>&nbsp;</p> <h1>Solution</h1> <p>This was actually the result of a typo.&nbsp; Not in the object namespace, but in the name of my variable name (not the value) when it was defined.&nbsp; So basically, it was because I was passing in a null value where a string was expected.&nbsp; See <a href="https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.clientcontext_members.aspx" target="_blank">ClientContext members</a> for more details.&nbsp; If it had actually been because the assembly was not loaded, the message would have been more like this</p> <p><img src="https://msdnshared.blob.core.windows.net/media/2016/12/BigContext.jpg"></p> <blockquote> <p>New-Object : Cannot find type [Microsoft.SharePoint.Client.BigClientContext]: verify that the assembly containing this type is <br>loaded.<br>At line:1 char:18<br>+ ... ntContext = New-Object Microsoft.SharePoint.Client.BigClientContext($ ...<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidType: (:) [New-Object], PSArgumentException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand<br></p> <p>&nbsp;</p></blockquote> <h1>Feedback</h1> <p>As always, if you do have any feedback or suggestions, I’d love to hear from you. </p> <p>You can also follow me on twitter <a href="https://twitter.com/RCormier_MSFT">@RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>How to: Parse Health Analyzer [OrphanApp] Entries</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/how-to-parse-health-analyzer-orphanapp-entries</link>
      <pubDate>Tue, 29 Nov 2016 18:44:52 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/?p=345</guid>
      <description><![CDATA[This post is going to provide a quick overview of how we can parse through messages in the health...]]></description>
      <content:encoded><![CDATA[<p>This post is going to provide a quick overview of how we can parse through messages in the health analyzer in order to identify all of the [OrphanApp] references that can be found in the ‘Missing server side dependencies’ problem that is reported by the health analyzer in SharePoint.</p> <p>&nbsp;</p> <h1></h1> <h1>Background</h1> <p>I was recently working with a customer who had an abnormally large number of [OrphanApp] entries in their health analyzer rule.&nbsp; This produced a very large number of instances of a message similar to the following – so much so that manually reading through and validating each of these entries became a very cumbersome task</p> <blockquote> <p>[OrphanApp] App [af6f2dd4-c702-406d-a792-11c2355749db] is orphaned in the database [O365Hybrid_ContentDB1] on site collection [9c64e5d0-aaac-4037-867e-0b77c334529f]. Orphaned Apps are not accessible, cause unnecessary resource and license consumption and may fail upgrade. Try to uninstall this App. App [af6f2dd4-c702-406d-a792-11c2355749db] is orphaned in the database [O365Hybrid_ContentDB1] on site collection [9c64e5d0-aaac-4037-867e-0b77c334529f]. Try to uninstall this App. If the App uninstallation is failing, it needs to be unblocked before the orphan App can be removed.</p></blockquote> <p>This was further complicated by the fact that any of the site collections that we verified (Get-SPSite –Identity 9c64e5d0-aaac-4037-867e-0b77c334529f) confirmed that the site did not exist in the environment</p> <p>&nbsp;</p> <h1>Approach</h1> <p>The overall approach in this case was pretty straightforward</p> <ol> <li>Get the contents of the list item that contains all of the [OrphanApp] entries  <li>Parse the message to isolate the site collection ID, the app ID and the content database name  <li>Verify that the site collection exists by using <a href="https://technet.microsoft.com/en-us/library/ff607950.aspx" target="_blank">Get-SPSite</a>  <li>Export the results to a human-readable format using <a href="https://technet.microsoft.com/en-us/library/ee176825.aspx" target="_blank">Export-CSV</a></li></ol> <p>&nbsp;</p> <h1>Solution</h1> <h2>Part 1</h2> <p>Let’s start with getting the contents of the list item that contains all of the [OrphanApp] entries.&nbsp; These live within a list called ‘Review Problems and Solutions’, which exists in the root web of your central administration site collection, so we can retrieve that pretty easily with the following PowerShell:</p> <blockquote> <p>$HealthList = (get-spweb https://CentralAdminURL).Lists["Review Problems and Solutions"]</p></blockquote> <p>Next we would want to target the individual list item that contains our [OrphanApp] entries, in this case, the title will be ‘Missing server side dependencies.’.&nbsp; We can retrieve this item pretty easily by using the following PowerShell</p> <blockquote> <p>$HealthListItem = $HealthList.getitems() | ? {($_['Severity'] -ne "4 - Success") -and ($_['Title'] -eq "Missing server side dependencies.")}</p></blockquote> <p>This will return the entire list item, but in this case we are only interested in the ‘Explanation’ field.&nbsp; Again, this is easily accessible using the following PowerShell:</p> <blockquote> <p>$HealthExplanation = $HealthListItem[‘Explanation’]</p></blockquote> <h2>Part 2</h2> <p>Now we have the entire string of data that we need to parse, which will include multiple entries.&nbsp; These are separated with hard carriage returns, so we can actually split the ‘Explanation’ into all of the individual messages in this case by using <a href="https://technet.microsoft.com/en-us/library/hh847811.aspx" target="_blank">Split</a> as shown the following PowerShell:</p> <blockquote> <p>$Messages = $HealthExplanation.Split(“`r`n”)</p></blockquote> <p>This will then result in a collection of messages, which we can iterate through by using a <a href="https://msdn.microsoft.com/en-us/powershell/reference/3.0/microsoft.powershell.core/foreach-object" target="_blank">foreach</a> loop</p> <p>Once we are in our foreach loop, we’re going to use <a href="https://technet.microsoft.com/en-us/library/2007.11.powershell.aspx" target="_blank">regular expression</a> (or RegEx) to extract the information that we need.&nbsp; Let’s start with the database name.&nbsp; If we refer to the message above, we can see that the content database name is the only instance where we see words enclosed in square brackets after the [OrphanApp] entry, so we would use the following regular expression in PowerShell to extract that information from the string:</p> <blockquote> <p>$DatabaseName = ([Regex]"\`[\w*\`]").Matches($Message)[1].Value.replace("[","").Replace("]","")</p></blockquote> <p>What this is doing is finding the [1] (or second) position in the array of objects (strings) that are returned when we look for a pattern that matches ‘[some words]’.&nbsp; This accounts for the [OrphanApp] entry at the start of the array, which would be position [0].&nbsp; The two instances of ‘.replace’ are used to strip the leading and trailing square brackets so that we return only the string.</p> <p>Next we will extract the app ID and the site collection ID from the message using two very similar Powershell examples.&nbsp; Again we will use regular expression.&nbsp; Let’s take a look at how we extract the app ID in the first example.&nbsp; The format of these messages is pretty standard and uniform.&nbsp; The first GUID that we see in the message is going to be the app ID.&nbsp; So we’re going to use the following PowerShell example to extract the first GUID from the message:</p> <blockquote> <p>$AppGUID = ([Regex]"\`[[a-fA-F0-9]{8}`-([a-fA-F0-9]{4}`-){3}[a-fA-F0-9]{12}\`]").Matches($Message)[0].Value.Replace("[","").Replace("]","")</p></blockquote> <p>Let’s look at the RegEx formula that we’re using and break it down into its components quickly before moving on.&nbsp; Each of these patterns must be matched in succession:</p> <ol> <li><strong>\`[&nbsp; </strong>: We need to escape the ‘[‘ character, because this has special meaning in regular expression  <li><strong>[a-fA-F0-9]{8}</strong> : This includes all characters that could be used in a GUID, upper and lower case.&nbsp; We’re looking specifically for 8 characters that match this pattern  <li><strong>`-</strong> : We need to escape the ‘-‘ character, because this has special meaning in a regular expression  <li><strong>([a-fA-F0-9]{4}`-){3}</strong> : Again, this includes all characters that could be used in a GUID, we are looking for 3 successive instances of 4 acceptable characters, each followed by a ‘-‘  <li><strong>[a-fA-F0-9]{12}</strong> : Again, this includes all acceptable characters that could be used in a GUID.&nbsp; We are looking specifically for 12 characters that match this pattern  <li><strong>\`]</strong> : We need to escape the ‘]’ character, because this has special meaning in regular expression</li></ol> <p>All put together, this regular expression (‘\`[[a-fA-F0-9]{8}`-([a-fA-F0-9]{4}`-){3}[a-fA-F0-9]{12}\`]’) will match any GUID which is enclosed in square brackets.</p> <p>In this case, as we mentioned, the app ID will be the first GUID extracted from the message that is provided by the health analyzer, this is denoted by .Matches($Message)<strong>[0]</strong> in the example above.</p> <p>The site collection ID will be the second GUID extracted from the message, so in that case the RegEx we use doesn’t change dramatically:</p> <blockquote> <p>$SCGUID = ([Regex]"\`[[a-fA-F0-9]{8}`-([a-fA-F0-9]{4}`-){3}[a-fA-F0-9]{12}\`]").Matches($Message)[1].Value.Replace("[","").Replace("]","")</p></blockquote> <p>The only difference in this case is that we target the second match returned, as denoted by .Matches($Message)<strong>[1]</strong>.</p> <h2>Part 3</h2> <p>Now that we have extracted the site collection ID, it’s pretty straightforward for us to use that information in a simple Get-SPSite script</p> <blockquote> <p>Get-SPSite $SCGUID -ErrorAction 0</p></blockquote> <p>I use the –ErrorAction 0 (silently continue) in this case because I know that many of the site collection IDs that are referenced do not correspond to actual sites in the environment.&nbsp; It’s not really error handling, but it’s preventing a flood of red from being output to the screen.&nbsp; If this returns a site collection object, the site exists. If it returns nothing, then the site collection does not exist in the environment.</p> <h2>Part 4</h2> <p>Now that we have all of the information we need to collect, outputting the information to a CSV is a pretty simple way to make it human readable and portable.&nbsp; We can do this by putting all of the information we need into a <a href="https://msdn.microsoft.com/en-us/library/system.management.automation.pscustomobject(v=vs.85).aspx" target="_blank">PSCustomObject</a>.&nbsp; We do this by using the following PowerShell script:</p> <blockquote> <p>$LoggingInformation = [PSCustomObject] @{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DatabaseName = $DatabaseName<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AppGUID = $AppGUID<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SiteCollectionGUID = $SCGUID<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SiteExists = $SiteExists<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p></blockquote> <p>This will effectively declare a new variable (PSCustomObject class) named LoggingInformation and set various properties (DatabaseName, AppGUID, SiteCollectionGUID, SiteExists) to values that were previously retrieved.&nbsp; We can then export this object to a CSV using the following PowerShell script:</p> <blockquote> <p>$LoggingInformation | Export-Csv –Path “c:\sharepoint\output.csv -Append –NoTypeInformation</p></blockquote> <p>In this case, the LogingInformation variable is considered the input object.&nbsp; I’m using the ‘Append’ switch to ensure that the information is added to the end of the CSV and the ‘NoTypeInformation’ switch just so that we don’t export type information for every object exported</p> <p>&nbsp;</p> <h1>Download the Script</h1> <p>I’ve created a script that puts all of this together for you, and you can download it from the TechNet script gallery.&nbsp; There you will be able to find usage details that will help you execute the script.</p> <p><a href="https://gallery.technet.microsoft.com/Get-OrphanedApps-ac83d025" target="_blank">Download Get-OrphanedApps.ps1</a></p> <p>&nbsp;</p> <h1>Feedback</h1> <p>As usual, if you do happen to have any feedback or suggestions regarding how I could improve this script, feel free to reach out to me.</p> <p>You can also follow me on twitter: </p> <p><a href="https://twitter.com/RCormier_MSFT" target="_blank">@Rcormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Test-SPContentDatabase: Cannot open database [DatabaseName] requested by the login. The login failed.</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/test-spcontentdatabase-cannot-open-database-databasename-requested-by-the-login-the-login-failed</link>
      <pubDate>Mon, 28 Nov 2016 22:40:50 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/?p=285</guid>
      <description><![CDATA[This blog post is going to cover a scenario where a, perhaps, confusing error message is returned to...]]></description>
      <content:encoded><![CDATA[<p>This blog post is going to cover a scenario where a, perhaps, confusing error message is returned to a SharePoint administrator when trying to verify the health/suitability of a content database by using <a href="https://technet.microsoft.com/en-us/library/ff607941.aspx" target="_blank">Test-SPContentDatabase</a></p> <p>&nbsp;</p> <h1>Background</h1> <p>I had been working with a customer on some health reporting scripts, and one of the validation steps was to run Test-SPContentDatabase against databases that were identified to contain orphaned apps.&nbsp; While manually running Test-SPContentDatabase, under the context of the SharePoint Farm Administrator account the SharePoint administrator received a very confusing message.&nbsp; The message was: ‘Cannot open database [DatabaseName] requested by the login. The login failed.’</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/11/Test-SPContentDatabase_1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2016/11/Test-SPContentDatabase_1.jpg"></a></p> <h1>Approach</h1> <p>As we were very sure that the farm account had sufficient rights to access this database (everything else appeared to be working normally and we had run other PowerShell cmdlets against this database in the past) we were suspicious that the error message returned may have been erroneous.</p> <p>We just took a quick look at the available parameters for this cmdlet using <a href="https://technet.microsoft.com/en-us/library/ee176848.aspx" target="_blank">Get-Help</a></p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/11/Test-SPContentDatabase_2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2016/11/Test-SPContentDatabase_2.jpg"></a></p> <p>&nbsp;</p> <h1></h1> <h1>Solution</h1> <p>A quick look through the parameters, and we knew that we had simply forgotten to specify the ServerInstance parameter.&nbsp; This was necessary because the database we were testing was not located on the default database server (I would love to link to an official Microsoft article that explains where and how to do this, but the latest article I can find on this topic is for SharePoint 2007 – nonetheless, it is a pretty straightforward process)</p> <p>As suspected, the error message was incorrect.&nbsp; This was not a logon issue, SharePoint was looking for a database on an instance where it did not exist.&nbsp; In the end, we simply added the –ServerInstance parameter, and Test-SPContentDatabase completed successfully</p> <p>&nbsp;</p> <h1>Feedback</h1> <p>As always, if you do have any feedback or suggestions, I’d love to hear from you.</p> <p>You can also follow me on twitter <a href="https://twitter.com/RCormier_MSFT" target="_blank">@RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>How To: Perform Bulk Uploads of Files to SharePoint</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/how-to-perform-bulk-uploads-of-files-to-sharepoint</link>
      <pubDate>Wed, 01 May 2013 08:16:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/2013/05/01/how-to-perform-bulk-uploads-of-files-to-sharepoint/</guid>
      <description><![CDATA[This post is going to discuss how to perform a bulk file copy from a folder on the file system to a...]]></description>
      <content:encoded><![CDATA[This post is going to discuss how to perform a bulk file copy from a folder on the file system to a SharePoint document library. Along with this blog post, I will also provide a downloadable script, which can be modified to work in your environment. As we are copying files from the file system to SharePoint, required metadata may need to be populated via default values or via modification to the script. Additional work could be performed in order to import the metadata from an xml file. This functionality is currently not available in the version of the script provided. This version of the script simply takes exactly what is on the file system and duplicates it in a SharePoint document library.

&nbsp;
<h1>Background</h1>
&nbsp;

I was recently working with a customer who needed to copy files from one SharePoint environment to another SharePoint environment. Although SharePoint does have this functionality built-in via <a target="_blank" href="https://technet.microsoft.com/en-us/library/ff607895(v=office.14).aspx">Export-SPWeb</a> and <a target="_blank" href="https://technet.microsoft.com/en-us/library/ff607613(v=office.14).aspx">Import-SPWeb</a>, this was not successful in the referenced environment. This was later determined to be related to corruption in the environment.

&nbsp;
<h1>Approach</h1>
&nbsp;

In this case, the approach was simple enough. Read the folder and file structure on the file system and replicate that structure in SharePoint.

&nbsp;
<h1>Solution</h1>
&nbsp;

The solution in this case is a little simpler than what was needed to originally export files from SharePoint to the file system, but the same basic principles apply. What's important in this case is to ensure that we create the folder structure before we start putting files in those folders. In order to do this, we need to be able to separate files from folders. We can use <a target="_blank" href="https://technet.microsoft.com/en-us/library/ee176841.aspx">Get-ChildItem</a> in order to accomplish this. Since we are only looking for folders, we can apply a filter.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/2068.GetAllFolders.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/2068.GetAllFolders.png" border="0" /></a>

Once we have a recursive list of all folders, we can loop through this list, creating each folder, and uploading the files in each folder as we go along. Retrieving a list of all files is also achieved by using Get-ChildItem using a slightly different set of filters.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/7318.GetChildItem.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/7318.GetChildItem.png" border="0" /></a>

Creating folders is done by using the $SPList.Folders.Add method. When we call this method, we'll have to pass the URL of the folder, the type of object to create, and the name of the folder. We also need to ensure that the folder is published, which can be performed by setting the "_ModerationStatus" property to "0". This is illustrated in the screenshot below.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/4666.CreateFolder.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/4666.CreateFolder.png" border="0" /></a>

Uploading Files to SharePoint is also relatively simple using PowerShell. We can use the $SPFolder.folder.files.add method for this. When we call this method, we need to pass a filename, the file stream, and a Boolean of whether or not to overwrite. We then need to perform certain tasks such as checking in, publishing and approving the file. This is illustrated in the screenshot below.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/4428.AddFile.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/4428.AddFile.png" border="0" /></a>

Once completed, the source directory and the destination library should look identical.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/7888.SourceDestination.png"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkImportFiles/7888.SourceDestination.png" border="0" /></a>

&nbsp;
<h1>Download the Script</h1>
&nbsp;

The script can be downloaded from the following location:
<a target="_blank" href="https://gallery.technet.microsoft.com/Bulk-Import-SharePoint-e5ab637c" title="BulkFileImport.ps1">BulkFileImport.ps1</a> (compressed)

&nbsp;
<h1>Usage</h1>
&nbsp;

This script does require some edits. All edits are explained at the top of the script. If you are using multiple source directories and/or multiple destination directories these can be chained together in a single script by inserting multiple iterations of the sample script block. Each source folder and destination library will need to be added to the script using the three lines of PowerShell which are included. Here is a brief explanation.

This line indicates which subfolder within the directory should be used for source files. Do note that this will be appended to the $Directory parameter set higher up in the script:
$SourceFolder = "PowerShell Scripts"

This line indicates which library within the SharePoint site collection the files should be imported to. This parameter should be the title of an existing list in the SharePoint environment:
$DestinationLibrary = $Site.RootWeb.Lists | ? {$_.title -eq "Shared Documents"}

This line calls the ImportFiles function and uses the source folder and the destination library as parameters:
ImportFiles ($Directory + "\" + $SourceFolder) $DestinationLibrary

&nbsp;
<h1>Feedback</h1>
&nbsp;

As always, feedback and suggestions are always welcome. If you do have any ideas on how to improve the script, I'd love to hear them.

You can also follow me on Twitter:

<a href="https://twitter.com/RCormier_MSFT">@Rcormier_MSFT</a>]]></content:encoded>
    </item>
    <item>
      <title>How to: Perform Bulk Downloads of Files in SharePoint</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/how-to-perform-bulk-downloads-of-files-in-sharepoint</link>
      <pubDate>Sat, 30 Mar 2013 18:26:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/2013/03/30/how-to-perform-bulk-downloads-of-files-in-sharepoint/</guid>
      <description><![CDATA[&nbsp;
This post is going to discuss how to perform a bulk file copy from a SharePoint library to a...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p>
<p>This post is going to discuss how to perform a bulk file copy from a SharePoint library to a folder on the file system. Along with this blog post, I will also provide a downloadable script, which can be modified to work in your environment. As we are copying files from SharePoint to the file system, all metadata will be stripped. Additional work could be performed in order to export the metadata to an xml file. This functionality is currently not available in the version of the script provided.</p>
<p>&nbsp;</p>
<h1>Background</h1>
<p>&nbsp;</p>
<p>I was recently working with a customer who needed to export files from one SharePoint environment and import them into another SharePoint environment. Though SharePoint does have this functionality built-in using <a href="https://technet.microsoft.com/en-us/library/ff607895(v=office.14).aspx">Export-SPWeb</a> and <a href="https://technet.microsoft.com/en-us/library/ff607613(v=office.14).aspx">Import-SPWeb</a>, in this case an export resulted in no files being exported from the desired directory. This was later determined to be corruption of the files after the export was unsuccessful on the desired directories.</p>
<p>&nbsp;</p>
<h1>Approach</h1>
<p>&nbsp;</p>
<p>In this case, the approach was simple enough. Read the folder and file structure from the specified list and replicate that structure on the file system.</p>
<p>&nbsp;</p>
<h1>Solution</h1>
<p>&nbsp;</p>
<p>This solution is tricky enough because of the way files are accessed in SharePoint lists. Enumerating all files in the list can be performed, however folder structure would not be maintained by calling $List.Items. In this case, what we have to do is perform two separate actions. One action to retrieve the root folder of the list and enumerate the items, and one action to enumerate each folder and each file in each folder. In order to do this, we call $List.rootfolder.files</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/8867.ListRootFiles.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/8867.ListRootFiles.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/8867.ListRootFiles.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/8867.ListRootFiles.png" alt="" border="0" /></a></p>
<p>We also need to enumerate all folder, and enumerate all of the files in each folder. This can be done by using $List.folders. This will list all folders (including subfolders) for the list.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/1121.ListAllFolders.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/1121.ListAllFolders.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/1121.ListAllFolders.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/1121.ListAllFolders.png" alt="" border="0" /></a></p>
<p>$Folder.folder.files allows you to enumerate all files in a specific folder</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/6305.ListFilesInFolder.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/6305.ListFilesInFolder.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/6305.ListFilesInFolder.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/6305.ListFilesInFolder.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>Now that we have a collection of all of the files and their directories, we can export the files to the file system. This can be performed by accessing the binary steam of the SharePoint file, and assigning it to the binary stream of a file system object. This is performed by using the following snippet of code.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/8715.BinaryStreamCode.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/8715.BinaryStreamCode.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/8715.BinaryStreamCode.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/8715.BinaryStreamCode.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>Once the script has been exported, the structure of the files and folders will be maintained on the file system as they were in the SharePoint site.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/1856.ExportResult.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/1856.ExportResult.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/BulkExportFiles/1856.ExportResult.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-BulkExportFiles/1856.ExportResult.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<h1>Download the Script</h1>
<p>&nbsp;</p>
<p>The script can be downloaded from the following location:<br /><a title="BulkFileExport.ps1" href="https://gallery.technet.microsoft.com/Bulk-Export-SharePoint-51857b22" target="_blank">BulkFileExport.ps1</a> (compressed)</p>
<p>&nbsp;</p>
<h1>Usage</h1>
<p>&nbsp;</p>
<p>This script does require some edits. All edits are explained at the top of the script. Each child directory must be specified in the script. Each library which is to be exported will need to be added to the script using the three lines of PowerShell which are included. Here is a brief explanation.</p>
<p>This next line will create a directory at the specified location. In this example, a directory will be made beneath the root directory and will be named StyleLibrary<br />New-Item -Path ($Directory + "\StyleLibrary") -ItemType Directory</p>
<p style="background: white;">&nbsp;</p>
<p>This next line will retrieve a list with the specified title, and assign it to a variable. The variable name is not important, as long as the correct variable is passed to the ExportFiles Function in the next line<br />$StyleLibrary = $Site.RootWeb.Lists | ? {$_.title -eq "Style Library"}</p>
<p>&nbsp;</p>
<p>This next line will export files from the list specified via the first variable and to the subdirectory specified in the second variable.<br />ExportFiles $StyleLibrary "StyleLibrary"</p>
<p>&nbsp;</p>
<h1>Feedback</h1>
<p>&nbsp;</p>
<p>As always, feedback and suggestions are always welcome. If you do have any ideas on how to improve the script, I'd love to hear them.</p>
<p>You can also follow me on Twitter:</p>
<p>&nbsp;<a title="RCormier_MSFT" href="https://twitter.com/RCormier_MSFT" target="_blank">RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>How to Copy SharePoint Documents Between Site Collections Using PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/how-to-copy-sharepoint-documents-between-site-collections-using-powershell</link>
      <pubDate>Fri, 16 Nov 2012 06:29:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/2012/11/16/how-to-copy-sharepoint-documents-between-site-collections-using-powershell/</guid>
      <description><![CDATA[This post is going to discuss copying SharePoint list items between site collections using...]]></description>
      <content:encoded><![CDATA[<p>This post is going to discuss copying SharePoint list items between site collections using PowerShell. Similar to other "How to with PowerShell" blog posts that I have written, I'm also going to provide you with a downloadable script. The sample script that I provide will effectively copy all documents from a specified source library to another specified destination library. The net result will be that all files from the source location will be copied to the destination location, with metadata preserved and intact. The exceptions in this case for metadata being created by, created date and time, modified by, and modified date and time. Version history is also not preserved. It may be possible to preserve some of this metadata as well, so please feel free to leave your comments and suggestions below or to any of the sample scripts I provide and create your own.</p>
<h1>Background</h1>
<p>I was working with a customer recently who needed to move a subset of their data from one site collection to another in order to provide representative data to a group of developers. The data provided had to be portable, but also had to be dynamically collected using values provided by certain business units. What we had decided on in the end was a site collection which contained the necessary data. This site collection would be stored in its own content database, and that content database could be packaged with the images used to create developer environments.</p>
<h1>Approach</h1>
<p>The approach that we had decided on was simple in theory. Determine which items we wished to include in the new site collection, and duplicate the data as needed. If we hadn't had complicated filters, we could use content deployment to get the job done. If we weren't moving the data into a remote site collection, we could use the MoveTo method that each file has, etc. But for our specific requirements, things would have been a lot easier.</p>
<h1>Solution</h1>
<p>As I mentioned, the first thing we had to do was determine which files we wanted to include in our representative data. This is pretty straightforward. First get the web that contains the list, then get the list, then get the items you want. In this example, we use <a href="https://technet.microsoft.com/en-us/library/ff607807.aspx">Get-SPWeb</a> to get the web, then we use the <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.lists.aspx">SPWeb.Lists</a> property to return the lists we want, and then we can use the <a href="https://www.bing.com/search?q=SPList.items">SPList.Items</a> property to retrieve the items we want. Of course, each of these can accept filters via a piped statement, such as:<br />$MyList = $MyWeb.Lists | ? {$_.title &ndash;eq "Shared Documents"}</p>
<p>In this example, I'm pulling all items from a library with only two items</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/CopyFiles/5481.FileList.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-CopyFiles/5481.FileList.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/CopyFiles/5481.FileList.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-CopyFiles/5481.FileList.png" alt="" border="0" /></a></p>
<p>Here is a screenshot of the original list in the browser</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/CopyFiles/3731.SourceLibrary.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-CopyFiles/3731.SourceLibrary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/CopyFiles/3731.SourceLibrary.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-CopyFiles/3731.SourceLibrary.png" alt="" border="0" /></a></p>
<p>Now that I have a collection of files, I need to loop through my files and send them to my desired destination. This process is a little more complicated than I had envisioned it to be originally. I'm going to summarize in this blog post, however you can refer to the comments in my script for more detail as to what steps and decisions are being made along the way.</p>
<p>One of the first things that I do in my loop is pull out the binary stream from the file, using the <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.openbinary.aspx">SPFile.OpenBinary</a> method, and assign that to a variable. I'll be using this later to populate the contents of the destination file. Next I'll be creating a new file by calling the <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfilecollection.add.aspx">SPFileCollection.Add</a> method in the destination library. After the file is created, I then retrieve a list of all <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.fields.aspx">SPListItem.Fields</a> objects that are not read-only and compare those to <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.properties.aspx">SPFile.Properties</a> of the source file and the destination file. For each property, if the property does not exist for the destination file, I create the field using <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.addproperty.aspx">SPFile.AddProperty</a>. Finally I set the value of the property using SPFile.Properties on the destination file, passing the same value that exists on the source document.</p>
<p>Again, there are a lot of little things happening here, and instead of posting a screenshot for each step, it's probably easier to refer to the comments in the example script I provide.</p>
<p>The result should be that your destination library will have exactly the same files in exactly the same folder structure as source library, as shown in the following screenshot:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/CopyFiles/5468.DestinationLibrary.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-CopyFiles/5468.DestinationLibrary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/CopyFiles/5468.DestinationLibrary.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-CopyFiles/5468.DestinationLibrary.png" alt="" border="0" /></a></p>
<h1>Download The Script</h1>
<p>This script can be downloaded from the following location:<br /><a title="Download CopyFilesAndFolders.ps1" href="https://gallery.technet.microsoft.com/Copy-all-SharePoint-Files-0999c53f" target="_blank">Download CopyFilesAndFolders.ps1</a> (zipped)</p>
<h1>Usage</h1>
<p>The script requires four parameters to be set. These correspond to the <strong>source web</strong>, the <strong>source library title</strong>, the <strong>destination web</strong>, and the <strong>destination library title.</strong>&nbsp; Edit these four parameters to suit your environment and then execute the script.</p>
<h1>Feedback</h1>
<p>As always, feedback and suggestions are always welcome. If you do have any ideas on how to improve the script, I'd love to hear them.</p>
<p>You can also follow me on Twitter:</p>
<p>&nbsp;<a title="RCormier_MSFT" href="https://twitter.com/RCormier_MSFT" target="_blank">RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Search Returns An Error: Object reference not set to an instance of an object</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/search-returns-an-error-object-reference-not-set-to-an-instance-of-an-object</link>
      <pubDate>Tue, 13 Nov 2012 17:09:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/2012/11/13/search-returns-an-error-object-reference-not-set-to-an-instance-of-an-object/</guid>
      <description><![CDATA[This post is going to talk about how to resolve the 'Object Reference not set to an instance of an...]]></description>
      <content:encoded><![CDATA[<p>This post is going to talk about how to resolve the 'Object Reference not set to an instance of an object' message you may run into when you perform a search from a SharePoint site. This is something you may run into most often when setting up a small lab environment, and I'll explain why below, as I go through resolving the issue.</p>
<h1>Background</h1>
<p>One of the greatest things about SharePoint, is that even after years of using the product, it will continue to find new ways to break that you've never seen before. And this is what happened to me. I had just built a new SharePoint 2010 farm in order to test some scripts that I had been working on. One of my customers was setting up PDF search in their SharePoint 2010 environment and was having an issue getting PDF documents to return in their search results. My first instinct was to send over this document:</p>
<p><a href="https://support.microsoft.com/kb/2293357">How to install and configure Adobe PDF iFilter 9 for SharePoint 2010</a></p>
<p>In response they indicated that they had been following this documentation and that it had in fact not worked. This documentation has always been solid for me, and has always done the trick &ndash; so I had to do some testing to make sure nothing changed, and that my guidance was still valid.</p>
<h1>Issue</h1>
<p>I had just created my new Search Service Application a few days prior, and I hadn't even performed a full crawl of the index yet. I followed the documentation, made my PDF icon appear and everything, uploaded some sample PDF documents and then kicked off a full crawl of my SharePoint sites content source. Everything looked great, and I had over 300 items in my index. Everything looked great until I did a search. Once I performed a search, I was greeted with an "Object reference not set to an instance of an object" message, and a correlation ID. Using <a href="https://technet.microsoft.com/en-us/library/ff607721(v=office.14).aspx">Merge-SPLogFile</a>, I passed in the correlation ID and got the following output (cleaned it up a little so that it's somewhat readable):</p>
<p>Videntityinfo::isFreshToken reported failure.</p>
<p>CoreResultsWebPart::OnInit: Exception initializing: <strong>System.NullReferenceException: Object reference not set to an instance of an object.</strong> at <strong>Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.SetPropertiesOnQueryReader()</strong> at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnInit(EventArgs e)</p>
<p>Internal server error exception: System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.SetPropertiesOnQueryReader() at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnInit(EventArgs e) System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.SetPropertiesOnQueryReader() at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnInit(EventArgs e)</p>
<p>Watson bucket parameters: SharePoint Server 2010, ULSException14, 06175311 "sharepoint server search", 0e00178d "14.0.6029.0", 17853a8f "microsoft.office.server.search", 0e0017ee "14.0.6126.0", 5021bda3 "tue aug 07 18:15:15 2012", 000032a1 "000032a1", 0000002d "0000002d", 4a6d3421 "nullreferenceexception", 67316a39 "g1j9"&nbsp;&nbsp;&nbsp;&nbsp;ff503ece-c286-454b-a5f2-998ca970808f</p>
<h1>What does this mean?</h1>
<p>So here's what I understood from this: My Core Results Web Part needed access to something, and it wasn't available or did not exist. I just had no idea what could have been missing. I've set SharePoint search up hundreds of times. I walked through my configuration, made sure that all of the services were started, and made sure that everything looked like it was properly configured.</p>
<h1>That Eureka moment</h1>
<p>Looking at my configuration, and then mentally walking through the process, it had sort of donned on me. I had two servers in my farm. One for all web functions, and one for all application functions. My Search query and site setting service, and my SharePoint Enterprise Search Service Application Proxy both existed on the application server AND I was using my app server as my browser. I had forgotten to follow this document on my application server:</p>
<p><a href="https://support.microsoft.com/kb/896861?wa=wsignin1.0">You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version</a></p>
<p>For anyone who is not familiar with this document &ndash; this is the famous 'DisableLoopbackCheck' document. Whenever my query web part tried to access the proxy (hosted on the same server the request was coming from), it was being denied access and couldn't determine where the query component was even hosted.</p>
<h1>The solution</h1>
<p>After figuring this much out, all I had to do was run through the documentation create the DisableLoopbackCheck registry key on my application server. Once I created this key and rebooted the server, the problem went away. This allowed me to validate that the documentation for configuring PDF indexing in SharePoint 2010 was still valid and worked perfectly.</p>
<h1>Feedback</h1>
<p>As always, any feedback is always welcome.</p>
<p>You can also follow me on Twitter:</p>
<p><a href="https://social.technet.microsoft.com/Profile/Resources/Images/twitter.gif"><img style="max-width: 550px;" src="https://social.technet.microsoft.com/Profile/Resources/Images/twitter.gif" alt="" border="0" /></a>&nbsp;<a title="RCormier_MSFT" href="https://twitter.com/RCormier_MSFT" target="_blank">RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Creating Claims-Based Web Applications in SharePoint 2013</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/creating-claims-based-web-applications-in-sharepoint-2013</link>
      <pubDate>Tue, 30 Oct 2012 10:29:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/2012/10/30/creating-claims-based-web-applications-in-sharepoint-2013/</guid>
      <description><![CDATA[This post is going to talk about how to create claims-based web applications in SharePoint 2013....]]></description>
      <content:encoded><![CDATA[<p>This post is going to talk about how to create claims-based web applications in SharePoint 2013. This is actually something else that I ran into when I was configuring my own lab environment, and everybody will run into this at one point or another in the lifecycle of their SharePoint 2013 environment. The reason for that is that Windows classic mode authentication is deprecated in SharePoint 2013. And this is well documented in this article:</p>
<p><a href="https://technet.microsoft.com/en-us/library/jj219758(v=office.15).aspx">What's new in authentication for SharePoint 2013</a></p>
<h1>Background</h1>
<p>As I said, I ran into this issue when I was configuring my own lab environment. I was using some existing scripts I had for SharePoint 2010, since most of them work, in order to create several web applications. If you haven't seen the documentation on TechNet, don't worry. SharePoint is pretty good about telling you that classic mode authentication has been deprecated in SharePoint 2013. This is a screenshot of what you will see if you configure a Windows classic mode authentication web application:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/ClaimsWebApp/2553.ClassicAuth.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-ClaimsWebApp/2553.ClassicAuth.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/ClaimsWebApp/2553.ClassicAuth.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-ClaimsWebApp/2553.ClassicAuth.png" alt="" border="0" /></a></p>
<p>This is the text contained in the informational message, in case you're encounter the issue:</p>
<p>WARNING: The Windows Classic authentication method is deprecated in this release and the default behavior of this cmdlet, which creates Windows Classic based web application, is obsolete. It is recommended to use Claims authentication methods. You can create a web application that uses Claims authentication method by specifying the AuthenticationProvider parameter set in this cmdlet. Refer to the <a href="https://go.microsoft.com/fwlink/?LinkId=234549">https://go.microsoft.com/fwlink/?LinkId=234549</a> site for more information. Please note that the default behavior of this cmdlet is expected to change in the future release to create a Claims authentication based web application instead of a Windows Classic based web application.</p>
<p>The good news is, we won't have to think about this forever &ndash; and it will end up being automatic eventually.</p>
<h1>Issue</h1>
<p>I ran into a few issues with this. The first issue I ran into with this was that using my SharePoint 2010 scripts and simply passing the AuthenticationProvider parameter my web applications were not consistently being deployed using windows claims authentication. The first web application would get created with windows claims authentication, every subsequent web application would ignore the AuthenticationProvider parameter and the web application would be created using windows classic authentication.</p>
<p>When this occurred, this would set off a chain of failures in my scripts, particularly when creating web application policies and assigning object cache accounts. The error message that you when this happens is also pretty helpful, and shouldn't set you back too far. Here's a screenshot:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/ClaimsWebApp/1563.NotClassicUser.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-ClaimsWebApp/1563.NotClassicUser.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/ClaimsWebApp/1563.NotClassicUser.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-ClaimsWebApp/1563.NotClassicUser.png" alt="" border="0" /></a></p>
<p>This is the text contained in the error message, in case you encounter the issue:</p>
<p>The specified principal does not correspond to the authentication mode of this collection</p>
<h1>Resolution</h1>
<p>I never did find out why I was having inconsistent AuthenticationProvider behavior. It was however resolved by rewriting my PowerShell script, and breaking everything out into functions created using claims authentication. I've made the script that I'm using available in the TechNet Gallery. The script itself does have a significant amount of conflict and error detection, and should make deploying claims authentication web applications in SharePoint Server 2013 pretty simple.</p>
<h1>Download</h1>
<p>The script can be downloaded from the following location: <br /><a title="Download CreateSP2013ClaimsWebApplication.ps1" href="https://gallery.technet.microsoft.com/Create-SharePoint-2013-1d7c3337" target="_blank">Download CreateSP2013ClaimsWebApplication.ps1</a> (zipped)</p>
<h1>Feedback</h1>
<p>As always, if you have any questions or feedback, let me know. If you have any ideas to optimize the script, I'd like to hear that too. Thanks for reading!</p>
<p>You can also follow me on Twitter:</p>
<p><a href="https://social.technet.microsoft.com/Profile/Resources/Images/twitter.gif"><img style="max-width: 550px;" src="https://social.technet.microsoft.com/Profile/Resources/Images/twitter.gif" alt="" border="0" /></a>&nbsp;<a title="RCormier_MSFT" href="https://twitter.com/RCormier_MSFT" target="_blank">RCormier_MSFT</a></p>]]></content:encoded>
    </item>
    <item>
      <title>You Shall Configure your MAXDOP When Using SharePoint 2013</title>
      <link>https://docs.microsoft.com/archive/blogs/rcormier/you-shall-configure-your-maxdop-when-using-sharepoint-2013</link>
      <pubDate>Wed, 24 Oct 2012 23:40:00 GMT</pubDate>
      <dc:creator><![CDATA[Roger Cormier]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rcormier/2012/10/24/you-shall-configure-your-maxdop-when-using-sharepoint-2013/</guid>
      <description><![CDATA[In this post, I'm going to talk about why and how to configure your Maximum Degree of Parallelism on...]]></description>
      <content:encoded><![CDATA[<p>In this post, I'm going to talk about why and how to configure your Maximum Degree of Parallelism on your SQL database instance. The reason I'm explaining this now is because of something I ran into while setting up my first SharePoint Server 2013 RTM farm tonight.</p>
<h1>Background</h1>
<p>Microsoft has been telling customers for years to set their Maximum Degree of Parallelism (MAXDOP) to 1 for SQL instances which host SharePoint database. For the most part, this guidance has been widely ignored with very little consequence, with the exception perhaps of sub-optimal performance.</p>
<p>For those of you who are unfamiliar with what this setting actually does, you can refer to the following documents:<br /><a href="https://technet.microsoft.com/en-US/library/ms181007(v=SQL.90).aspx" target="_blank">max degree of parallelism Option</a><br /><a href="https://support.microsoft.com/kb/2023536" target="_blank">Recommendations and Guidelines for 'max degree of parallelism' configuration option</a></p>
<p>The second link actually does a pretty good job of explaining in detail what this option does &ndash; and here's the short summary: The SQL Server configuration option 'max degree of parallelism' controls the number of processors used for the execution of a query with a parallel plan.</p>
<p>A higher MAXDOP value would typically be used when you have a very small number of concurrently executing queries relative to the number of processors. A lower MAXDOP value would typically be used when you have a very large number of concurrently executing queries relative to the number of processors. The default value of '0' will effectively limit the MAXDOP value to the number of processors.</p>
<p>SharePoint is a system in which there will be a very high number of concurrently executing queries; therefore this system favors a lower MAXDOP value. As indicated in the following documents, the optimal MAXDOP value for SharePoint environments is 1.<br /><a href="https://technet.microsoft.com/en-us/library/cc298801.aspx" target="_blank">Storage and SQL Server capacity planning and configuration (SharePoint Server 2010)</a><br /><a href="https://technet.microsoft.com/en-us/library/ff758650.aspx" target="_blank">Enterprise intranet collaboration environment technical case study (SharePoint Server 2010)</a></p>
<p>Historically, Microsoft has been making this recommendation, and adding query hints in order to limit MAXDOP for each query to 1 in order to limit the impact of setting MAXDOP to any value other than 1, or leaving it at 0. This does not appear to be necessary going forward, and I'll do my best to explain why.</p>
<h1>What Happens If I Haven't Set MAXDOP to 1?</h1>
<p>The answer here is pretty simple. If your MAXDOP value has not been set to 1 on the SQL server instance on which you're attempting to host your databases, you will not be able to create databases on the instance. The error message you will encounter is the following:</p>
<p><em>New-SPConfigurationDatabase : This SQL Server instance does not have the required "max degree of parallelism" setting of 1. Database provisioning operations will continue to fail if "max degree of parallelism" is not set 1 or the current account does not have permissions to change the setting. See documentation for details on manually changing the setting </em></p>
<p>Also seen in this screenshot:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/MAXDOP/3225.MAXDOP_0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-MAXDOP/3225.MAXDOP_5F00_0.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/MAXDOP/3225.MAXDOP_0.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-MAXDOP/3225.MAXDOP_5F00_0.png" alt="" border="0" /></a></p>
<h1>How Do I Work Around This Problem?</h1>
<p>There are basically two ways to remediate this issue. The first one (not recommended) is to grant the account running the PowerShell cmdlets, or executing the Configuration Wizard, sysadmin access to your SQL instance. The second, more desirable approach, is to set the MAXDOP value to 1 in the SQL instance.</p>
<p>The MAXDOP option is an advanced option. The documentation above does provide the SQL statements to change this option. I'll briefly explain how to do this using SQL Management Studio. My screenshot is from SQL Server 2012, the process will be the same for SQL Server 2008 R2, and SharePoint 2013 does not support older versions of SQL:</p>
<ol>
<li>Open SQL Management Studio and connect to the instance which will host SharePoint databases</li>
<li>Right-click the Instance you wish to manage</li>
<li>Select 'Properties'</li>
<li>Select the 'Advanced' Node</li>
<li>The Second option from the bottom will be 'Maximum Degree of Parallelism'. Change this value to 1</li>
<li>Click 'OK'</li>
</ol>
<p>Your value should appear as in the screenshot below:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/MAXDOP/4212.MAXDOP_1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-MAXDOP/4212.MAXDOP_5F00_1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/MAXDOP/4212.MAXDOP_1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-MAXDOP/4212.MAXDOP_5F00_1.png" alt="" border="0" /></a></p>
<p>After having set the MAXDOP value to 1, you should be able to proceed and create your farm and/or additional databases, all the while following at least one best practice.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/MAXDOP/8546.CreateFarm.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-MAXDOP/8546.CreateFarm.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/03/82/Images/MAXDOP/8546.CreateFarm.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-03-82-Images-MAXDOP/8546.CreateFarm.png" alt="" border="0" /></a></p>
<h1>What Does This Mean In The Enterprise?</h1>
<p>This should mean that enterprises will start to be a little more mindful of what kind of applications, if any, are going to share database instances with SharePoint. People in the enterprise need to consider what type of query patterns are going to be used in their applications, and whether or not the performance of these applications will be negatively impacted by having a MAXDOP value of 1. What I anticipate will happen is that we're going to see more SQL instances that are dedicated to hosting SharePoint databases, possibly for multiple farms, and overall I see this as a good move.</p>
<h1>Feedback</h1>
<p>As always, if you have any questions or feedback, let me know. I'd be interested in finding out what your thoughts are regarding this change in SharePoint 2013</p>
<p>You can also follow me on Twitter:</p>
<p><a href="https://social.technet.microsoft.com/Profile/Resources/Images/twitter.gif"><img style="max-width: 550px;" src="https://social.technet.microsoft.com/Profile/Resources/Images/twitter.gif" alt="" border="0" /></a>&nbsp;<a title="RCormier_MSFT" href="https://twitter.com/RCormier_MSFT" target="_blank">RCormier_MSFT</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>