Parameter name: userProfileApplicationProxy

Had a contractor leave the company and return. Often this creates issues because we don’t run a ‘dead account cleaner’ often enough.

To get around this, I run the script below to get the ‘new’ Active Directory account synced with the new Active Directory account.

Script:

$user = Get-SPUser -web "http://sharepointed.com" -Identity "Mydomain\TheUser"
Move-SPUser -Identity $user -newalias "Mydomain\TheUser" -IgnoreSID 

Where I went wrong… I remoted’ into one of the servers in the farm using my personal NT login. By doing this, I was receiving the error below. Once I remoted’ into the server using the Admin account, I was able to run the script.

Error:
Move-SPUser : Value cannot be null.
Parameter name: userProfileApplicationProxy
At line:1 char:12
+ Move-SPUser <<<< -Identity $user -newalias "Mydomain\TheUser" -IgnoreSID + CategoryInfo : InvalidData: (Microsoft.Share...PCmdletMoveUser: SPCmdletMoveUser) [Move-SPUser], ArgumentNullException + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletMoveUser

Inventory Web App Using PowerShell

Ask: We need an Excel spreadsheet that will list out all the Sites, List, Libraries for a given Web App in SharePoint.

Found this post link, then modified it for my needs.

function Get-WebAppInventory($WebAppName) {
    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
    $farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
    foreach ($spService in $farm.Services) {
        if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) {
            continue;
        }

        foreach ($webApp in $spService.WebApplications) {
            if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) { continue }
			if($webApp.name -eq $WebAppName)
			{
            foreach ($site in $webApp.Sites) {
                foreach ($web in $site.AllWebs) {
                        foreach ($list in $web.Lists) {
							$data = @{
								"Site" = $site.Url
                                "Web" = $web.Url
                                "list" = $list.Title
								"Type" = $list.BaseType	
								"Item Count" = $list.ItemCount
								"Last Item Modified" = $list.LastItemModifiedDate
							}
							
                            New-Object PSObject -Property $data
         
                    }
                }
            }
		}
        }
    }
}
#Get-WebAppInventory "SharePointed - name.sharepointed.com80" | Out-GridView
Get-WebAppInventory "SharePointed - name.sharepointed.com80" | Export-Csv -NoTypeInformation -Path c:\inventory2.csv

Above you have two options, Out-GridView or Export-CSV. You can use both or comment out one of the lines.

To get the parameter I’m passing to the function, you will need to look in Central Admin at your Web Apps list. Central Admin –> Application Management section –> Manage web applications. (_admin/WebApplicationList.aspx). In there, copy the name of the Web App.

You can modify the $data = @{ section to bring in other properties of the List.

Use PowerShell to Query The SharePoint Search Index

Needed to write a script to validate that the SharePoint crawler was picking up all items in a library.
One of my document libraries had over a 100,000 document, and I needed to make sure all of them were being indexed.
Document library can support millions of documents, IF you use a good foldering structure.

function GetSearchIndex ($site, $file)
	{
		$fOutPut = $null
		$kq = new-object Microsoft.Office.Server.Search.Query.KeywordQuery($site)
		
		$kq.ResultTypes= [Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults
		$kq.QueryText = $file
		$kq.HiddenConstraints = 'scope:"All Sites"'
		$kq.RowLimit = 10
		$res = $kq.Execute()
		
		$table = new-object System.Data.DataTable
		$table.Load($res[$kq.ResultTypes],[System.Data.LoadOption]::OverwriteChanges)
		
		if($table.Rows.Count -eq 0)
		{
			$fOut = "Failed"
		}
		else
		{
			$fOut = "Passed"
		}
		return $fOut
	}

$file = "c:\indexCheck.txt"
$cfcSite = Get-SPWeb "http://SOMEsite.sharepointed.com/sites/test"
$nv = $cfcSite.Lists["bigLibrary"]

$spQuery = New-Object Microsoft.SharePoint.SPQuery 
$spQuery.ViewAttributes = "Scope='Recursive'"
$spQuery.RowLimit = 2000 
$caml = '<OrderBy Override="TRUE"><FieldRef Name="ID"/></OrderBy>' 
$spQuery.Query = $caml 

do
{
    $listItems = $nv.GetItems($spQuery)
    $spQuery.ListItemCollectionPosition = $listItems.ListItemCollectionPosition
    foreach($item in $listItems)
    {
        $sResult = GetSearchIndex "http://test.sharepointed.com" $item.Name
		
		if($sResult -eq "Failed")
		{
			$item.Name | Out-File $file -Append			
		}
    }
}
while ($spQuery.ListItemCollectionPosition -ne $null)

Query the list/library in batches of 2,000.
Looping through the returned items.
Call function to see if the item is in the index (query SharePoint).
From the function, return a value of Passed or Failed.
If Failed is true, log it to a text file on the C:\ drive.

job admin apppool change FIXED

Error when trying to change the password for a Managed Account in SharePoint 2010:

Error deploying administration application pool credentials.
Another deployment may be active. An object of the type
Microsoft.SharePoint.Administration.SPAdminAppPoolCredentialDeploymentJobDefinition named
“job-admin-apppool-change” already exists under the parent Microsoft.SharePoint.Administration.SPTimerService named “SPTimerV4”. Rename your object or delete the existing object.

In my case, I needed to change the account that the SharePoint 2010 Timer service was running as. Every time I tried to update the password, the Timer would stop and the update would fail. Once I changed the Run As of the Timer, I was able to update the password.

Add-PSSnapin Microsoft.SharePoint.PowerShell -EA silentlycontinue

$m = Get-SPManagedAccount -Identity "domain\YourAccount"

Set-SPManagedAccount -Identity $m  -ExistingPassword (ConvertTo-SecureString "Your PASSWORD" -AsPlainText -force) –confirm

Paused by system

If your Search Service Application shows a crawl status of Paused for:External request or Paused by system . You can use the following script to get it back online.

$ssa = Get-SPEnterpriseSearchServiceApplication “YOUR Search Service Application name here”

Resume-SPEnterpriseSearchServiceApplication $ssa

*NOTE*
Your Search App might be named something different than Search Service Application.
To find your Searh App name, navigate to your Central Admin site, under Application Management, click on Manage service applications. In the Type column, look for an item that says Search Service Application.

and credit for this post goes to a super smart coworker.

Use PowerShell to Create SharePoint Groups

Simple enough, needed to create a few SharePoint groups and thought PowerShell would be the best answer.


$SiteUrl = "http://sharepointed.com/sites/a"
$Web = Get-SPWeb $SiteUrl

$description = “Super cool stuff”
$permissionLevel = “Read”

$groups = “Group A”, “Group B”, “Group C”

foreach($groupName in $groups)
{
$web.SiteGroups.Add($groupName, $web.SiteUsers[“domain\SomeUser”], $web.SiteUsers[“domain\SomeUser”], $description)
$group = $web.SiteGroups[$groupName]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($group)
$roleDefinition = $web.Site.RootWeb.RoleDefinitions[$permissionLevel]
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition)
$web.RoleAssignments.Add($roleAssignment)
$web.Update()
}

$web.SiteGroups.Add(name, owner, default user, description)

Parameters
name
Type: System.String
A string that represents the new group name.
owner
Type: Microsoft.SharePoint.SPMember
An SPMember object that specifies the owner.
defaultUser
Type: Microsoft.SharePoint.SPUser
An SPUser object that specifies the default user for the group.
description
Type: System.String
A string that contains a description for the group.

More details:
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spgroupcollection.add.aspx

To get all the uses / groups from a site or web see this post:

http://www.sharepointed.com/2016/10/17/get-all-groups-and-users-in-a-site-collection-or-web/

 

Monitor and Report on Long Running Crawls

Ever needed to know if your SharePoint crawls are running too long? I wrote the below script to keep an eye on my crawls, and report if they are running too long.

In the script, I’m getting the Search Service App. Looping through its content sources, then finding crawls that are running longer than 5 minutes.

#Get PowerShell Snapin
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
{
	Add-PsSnapin Microsoft.SharePoint.PowerShell
}

#get your Search Service App
$ssa = Get-SPEnterpriseSearchServiceApplication "Search Service Application"

#get the content sources from your Search Service App
$contentsources = Get-SPEnterpriseSearchCrawlContentSource -SearchApplication $ssa 


#loop through the content sources
foreach($cs in $contentsources)
{
	#check for crawls that are running
	if ($cs.CrawlStatus -ne "Idle")
	{			
		$cLength = New-TimeSpan -Start ($cs.CrawlStarted) -End (Get-Date) 
		$cLength = $cLength.Minutes
		
		#if the crawl has been running for more than X minutes, send an email
		if($clength -gt 5)
		{
			#email someone that cares
		}
	}
}

Cannot Undeclare Record in SharePoint

Using SharePoint Records Management, I declared a document as a record.  Then I tried to undeclare the document as a record.  For some reason SharePoint wouldn’t not undeclare the document.

Using PowerShell, you can force the undeclare action.

#Load the sharepoint snapin
$SPWeb = Get-SPWeb "http://sharepointed.com/sites/taco" 
  
$SPList = $SPWeb.Lists["Taco Recipes"]   
$SPItem = $SPList.GetItemById("75")     

#new code to remove hold first    
$SPItem.Properties.Remove("ecm_ItemLockHolders")
$SPItem.File.Properties.Remove("ecm_ItemLockHolders")   
$SPItem.SystemUpdate()    

#undeclare the record
[Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($SPItem)

 

Doing this will remove the lock from the document.

Use PowerShell to Update Item Permssions in SharePoint

What if you want to update the item permissions on every item in a list or library, BUT you don’t want to trigger an associated workflow?

Why?

Request came in to add a new SharePoint group to all the items in a library.  Options were to update EVERY item in the library and let the workflow update the permissions, update the items ONE AT A TIME…

OR

Use PowerShell to update item permissions and not stress the server(s).


# add powershell snapin
$web = Get-SPWeb -Identity "http://sharepointed.com"
$list = $web.Lists.TryGetList("Taco Time")
$group = "Taco Makers"
$PermissionLevel = "Read"

#get site group and setup permission/role
$group = $web.Groups[$group]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($group)
$roleDefinition = $web.RoleDefinitions[$PermissionLevel];
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition);

if ($list -ne $null)
{
	foreach ($item in $list.Items)
	{
		if ($item.HasUniqueRoleAssignments -eq $False)
		{
			$item.BreakRoleInheritance($True)
		}
	       
                if ($web.SiteGroups[$group] -ne $null)
		{
			$item.RoleAssignments.Add($roleAssignment)
		}
		else
		{
			Write-Host "Group is not valid."
		}		
	}
}
$web.Dispose()

Update People Picker Using PowerShell

Recently had a new domain added to our forest. After this happened, users would see duplicate values in the SharePoint people picker. The values would both look like John Doe and John Doe, but their underlying domains were different. This caused all sorts of fun when people started emailing “john doe can’t access my site.”

To fix this, the people picker property for each web application in the farm needed to be updated.

There are a lot of properties and options that you can update. I’m only updating my people picker to show one domain.

More on the people picker:
http://msdn.microsoft.com/en-us/subscriptions/cc263012(v=office.12).aspx


#add the powershell snapin

$contentWebAppServices = (Get-SPFarm).services |
 ? {$_.typename -eq "Microsoft SharePoint Foundation Web Application"}

foreach($webApp in $contentWebAppServices.WebApplications)
{
 Set-SPSite $webApp.Url -UserAccountDirectoryPath "DC=YourDomain,DC=Com"
}

What I’m doing is getting all the web applications in the SharePoint farm.  Looping through the applications and updating the people picker.