<# common functions #> $script:currentScriptVersion = "1.0" Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue #color to display status $couleurStatut = [ConsoleColor]::White #section color $couleurSousSection = [ConsoleColor]::DarkMagenta #decorated color $couleurDecoration = [ConsoleColor]::White #alert color $couleurAlerte = [ConsoleColor]::Yellow #ok color $couleurOK = [ConsoleColor]::Green #nok color $couleurNOK = [ConsoleColor]::Red #information color $couleurInfo = [ConsoleColor]::White $global:logActivated = $false; ########################################################################## # COMMON ########################################################################## function WriteLogo{ Write-Host " " } # restart sharepoint owstimer service function RestartServices() { $serviceName="SPTimerV4" Write-Host "Try Restart service on '$serviceName'..." -ForegroundColor White $farm = Get-SPFarm foreach($server in $farm.Servers) { if($server.Role -eq [Microsoft.SharePoint.Administration.SPServerRole]::Application -or $server.Role -eq [Microsoft.SharePoint.Administration.SPServerRole]::WebFrontEnd) { WriteDecoredMessage "Restart service on $($server.Name)" $serviceInstance = Get-Service -ComputerName $server.Name -Name $serviceName -ErrorAction SilentlyContinue; if($serviceInstance -ne $null) { try { $restartServiceOutput="" Restart-Service -InputObject $serviceInstance WriteDecoredMessage " OK!" } catch { Write-Error -Message $_.Exception.Message } } } } } function Get-ScriptDirectory { $Invocation = (Get-Variable MyInvocation -Scope 1).Value $global:currentFolder = $Invocation.MyCommand.Path.Substring(0, $Invocation.MyCommand.Path.LastIndexOf("\")); write-host $currentFolder Split-Path $Invocation.MyCommand.Path } #Write decorated message function WriteDecoredMessage{ param( [string]$Message = $(throw "Parameter [Message] required") ) Write-Host "-------------------------------------------------------------------------" -ForegroundColor $couleurDecoration Write-Host " " $Message -ForegroundColor $couleurDecoration Write-Host "-------------------------------------------------------------------------" -ForegroundColor $couleurDecoration Log -message $Message -messagetype "INFO" -writehost $false; } #write decorated line function WriteDecoredLine{ param( [string]$Message = $(throw "Parameter [Message] required") ) Write-Host "------- " $Message " -------" -ForegroundColor $couleurDecoration Log -message $Message -messagetype "INFO" -writehost $false; } #write operation succeded function WriteOperationSucceded{ param( [string]$Message = "Operation succeded push key enter to continue" ) Read-Host "------- " $Message Log -message $Message -messagetype "INFO" -writehost $false; } #Write message on line function WriteLineMessage{ param( [string]$Message = $(throw "Parameter [Message] required") ) Write-Host $Message -ForegroundColor $couleurStatut -NoNewLine Log -message $Message -messagetype "INFO" -writehost $false; } #Write ok message function WriteOK{ Write-Host " OK" -ForegroundColor $couleurOK } #write debug message function WriteDebug{ param( [string]$Message = $(throw "Parameter [Message] required") ) if($debug) { Write-Host $Message -ForegroundColor $couleurAlerte Log $Message "DEBUG"; } } #Write information message function WriteInfo{ param( [string]$Message = $(throw "Parameter [Message] required"), [ConsoleColor]$Color=[ConsoleColor]::White ) Write-Host $Message -ForegroundColor $color Log -message $Message -messagetype "INFO" -writehost $false; } #Write information message without passing at the next line function WriteInfoNoNewLine{ param( [string]$Message = $(throw "Parameter [Message] required"), [ConsoleColor]$color=[ConsoleColor]::White ) Write-Host $Message -ForegroundColor $color -NoNewline Log -message $Message -messagetype "INFO" -writehost $false; } #write error message function WriteError{ param( [string]$Message = $(throw "Parameter [Message] required") ) Write-Host $Message -ForegroundColor $couleurNOK Log -message $Message -messagetype "ERROR" -writehost $false; } #Succeded message function WriteSuccededMessage() { param( [string]$Message = "Operation succeded, push key enter to continue" ) Read-Host $Message Log -message $Message -messagetype "INFO" -writehost $false; } #ask for web application url function AskForWebApplicationUrl{ $url = Read-Host "Web application's url" while ($url -eq "" -or ((Get-SPWebApplication "$url" -ErrorAction SilentlyContinue) -eq $null)){ Write-Host "Invalid url" -ForegroundColor $couleurAlerte $url = Read-Host "Web application's url" } return $url } #ask for many web appplication urls function AskForMultipleWebApplicationUrl{ $webapps = @() $url = AskForWebApplicationUrl $webapps = $webapps + $url $reponse = Read-Host "Add an other web application ? (Y/N)" while ($reponse -eq "Y"){ $url = AskForWebApplicationUrl $webapps = $webapps + $url $reponse = Read-Host "Add an other web application ? (Y/N)" } return $webapps } #ask for site collection url function AskForSiteCollectionUrl{ $url = Read-Host "Site collection's url " while ($url -eq "" -or ((Get-SPSite "$url" -ErrorAction SilentlyContinue) -eq $null)){ Write-Host "Invalid URL" -ForegroundColor $couleurAlerte $url = Read-Host "Site collection's url" } return $url } #ask for site collection url function AskForSiteCollection{ $url = Read-Host "Site collection's url" while ($url -eq "" -or ((Get-SPSite "$url" -ErrorAction SilentlyContinue) -eq $null)){ Write-Host "Invalid url" -ForegroundColor $couleurAlerte $url = Read-Host "Site collection's url" } return Get-SPSite "$url" } #ask for url function AskForSiteUrl{ $url = Read-Host "Site's url " while ($url -eq "" -or ((Get-SPWeb "$url" -ErrorAction SilentlyContinue) -eq $null)){ Write-Host "Invalid URL" -ForegroundColor $couleurAlerte $url = Read-Host "Site's url" } return $url } #ask for list url function AskForList{ $url = Read-Host "List's url" $list = $null while ($list -eq $null){ if ($listurl -ne ""){ $site = $null $web = $null $site = New-Object -TypeName Microsoft.SharePoint.SPSite -ArgumentList $($url); $web = $site.OpenWeb() if ($web -ne $null){ try{ $list = $web.GetList($url) } catch{ Write-Host "Error : " $Error[0].Exception.Message -ForegroundColor $couleurNOK } } if ($web -ne $null){ $web.Dispose() } if ($site -ne $null){ $site.Dispose() } } if ($list -eq $null){ Write-Host "Url non valide" -ForegroundColor $couleurAlerte $url = Read-Host "Enter new url" } } return $list } #ask for my site url function AskForMySiteHostUrl{ $url = Read-Host "My site host's url" while ($url -eq "" -or ((Get-SPSite "$url" -ErrorAction SilentlyContinue) -eq $null) -or ((Get-SPSite "$url").RootWeb.WebTemplate -ne "SPSMSITEHOST")){ Write-Host "Invalid url. Site does not exist or is not a my site host" -ForegroundColor $couleurAlerte $url = Read-Host "add new url" } return $url } #ask for site url function AskForNewSiteUrl{ $SiteUrl = $null if($SiteUrl -eq $null -or $SiteUrl -eq "") { $SiteUrl = Read-Host "Enter new site's url" while ($SiteUrl -eq ""){ Write-Host "Invalid url" -ForegroundColor $couleurAlerte $SiteUrl = Read-Host "Enter new site's url" } } if ((Get-SPSite "$SiteUrl" -ErrorAction SilentlyContinue) -ne $null){ Write-Host "A site already exists at specified url, and will be removed" -ForegroundColor $couleurAlerte $reponse = Read-Host "Do you really want to use that url ? (Y/N)" if ($reponse -ne "Y"){ $SiteUrl = AskForNewSiteUrl } } return $SiteUrl } #ask for site template function AskForSiteTemplate{ $templateName = Read-Host "Which site template do you want to use ? (value of type SPS#0)" while ($templateName -eq "" -or ((Get-SPWebTemplate $templateName -ErrorAction SilentlyContinue) -eq $null)){ Write-Host "Invalid site template" -ForegroundColor $couleurAlerte $templateName = Read-Host "Which site template do you want to use ? (value of type SPS#0)" } return $templateName } #ask for login function AskForUser{ Param ( [string]$UserLogin ) if($UserLogin -eq $null -or $UserLogin -eq "") { $UserLogin = Read-Host "User's login : (DOMAIN\Login)" while ($UserLogin -eq ""){ Write-Host "Login non valide" -ForegroundColor $couleurAlerte $UserLogin = Read-Host "User's login (DOMAIN\Login)" } } return $UserLogin } #ask for string function AskForString{ $chaine = Read-Host "Pleaser provide a value" while ($chaine -eq ""){ Write-Host "not valid value" -ForegroundColor $couleurAlerte $chaine = Read-Host "Pleaser provide a value" } return $chaine } #ask active directory Synchronization function AskForADSynchroConnName{ $chaine = Read-Host "Please provide the name of the AD Synchronization connection" while ($chaine -eq ""){ Write-Host "Invalid Value" -ForegroundColor $couleurAlerte $chaine = Read-Host "Please provide the name of the AD Synchronization connection" } return $chaine } #Ouvre internet explorer avec l'adresse du site cible #SiteUrl - Obligatoire - Url du site function OpenIEForSite{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required") ) $sps = Get-SPSite $SiteUrl if ($sps -ne $null){ $sps.Dispose() $ie = New-Object -comObject InternetExplorer.Application $ie.visible = $true $ie.navigate($SiteUrl) } } #add property to propertybag function AddWebPropertyToRootWeb{ param( [string]$Key = $(throw "Parameter [Key] required"), [string]$Value = $(throw "Parameter [Value] required"), [string]$SiteUrl = $(throw "Parameter [Site] required") ) $site = Get-SPSite -Identity $SiteUrl $rootWeb = $site.RootWeb $auu = $rootWeb.AllowUnsafeUpdates $rootWeb.AllowUnsafeUpdates = $true; $Currentvalue = $rootWeb.Properties[$Key] if (!$rootWeb.Properties.ContainsKey($Key)) { $rootWeb.Properties.Add($Key, $Value); } else { $rootWeb.Properties[$Key] = $Value; } $rootWeb.Properties.Update(); $rootWeb.Update(); $rootWeb.AllowUnsafeUpdates = $auu $UpdatedValue = $rootWeb.Properties[$Key] if ($rootWeb -ne $null) { $rootWeb.Dispose() } If ($site -ne $null) { $site.Dispose(); } Write-Host -ForegroundColor $couleurStatut "Web property added " $UpdatedValue } ########################################################################## # DEPLOYMENT ########################################################################## #Wait For Deployment Job function WaitForDeploymentJob { param( [string]$SolutionName = $(throw "Parameter [SolutionName] required") ) $Solution = Get-SPSolution | ? {($_.Name -eq $SolutionName)} if ($Solution -ne $null) { while ($Solution.JobExists) { Write-Host "." -NoNewline Start-Sleep 2 } Write-Host "." } } #Copy DLL to App Bin Content function CopyAppBinContent { Write-Host "Copy in C:\Inetpub\wwwroot\wss\VirtualDirectories" $LocalContent = [Microsoft.SharePoint.Administration.SPWebServiceInstance]::LocalContent if($LocalContent -ne $null -and $LocalContent.Status -eq [Microsoft.SharePoint.Administration.SPObjectStatus]::Online) { [Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplyApplicationContentToLocalServer() } $LocalAdministration = [Microsoft.SharePoint.Administration.SPWebServiceInstance]::LocalAdministration if($LocalAdministration -ne $null -and $LocalAdministration.Status -eq [Microsoft.SharePoint.Administration.SPObjectStatus]::Online) { [Microsoft.SharePoint.Administration.SPWebService]::AdministrationService.ApplyApplicationContentToLocalServer() } Write-Host } #Uodate wsp function UpdateSolutions { param( [switch]$Confirm, [switch]$Force, [string]$WspFolder = $(throw "Parameter [WspFolder] required. should contains absolute path(sample Get-ScriptDirectory)") ) $files = get-childitem $WspFolder *.wsp [int]$count = 0 foreach($file in $files){ if ($file -ne $null){ WriteDecoredMessage -Message "Updating $file" [bool]$continue = $true if ($Confirm -eq $true) { $do = Read-Host "Confirm " $file "? (Y/N)" if ($do -ne "Y") { $continue = $false } } if ($continue) { $count = $count + 1 if ($Force){ Update-SPSolution -Identity "$file" -LiteralPath $(Join-Path -path $WspFolder -childpath "$file") -Force -GACDeployment } else { Update-SPSolution -Identity "$file" -LiteralPath $(Join-Path -path $WspFolder -childpath "$file") -GACDeployment } WaitForDeploymentJob -SolutionName $file } } } if ($count -gt 0){ Write-Host $count "solution(s) updated" } else{ Write-Host "no updates" } } #Retract, remove, add, deploy solution function RedeploySolution { param( [string]$FileName = $(throw "Parameter [FileName] required"), [string]$wspFolder, [string[]]$WebApps, [switch]$Confirm, [switch]$Force ) WriteDecoredLine -Message $FileName [bool]$continue = $true if ($Confirm -eq $true) { $do = Read-Host "Confirm " $file "? (Y/N)" if ($do -ne "Y") { $continue = $false } } if ($continue) { $solution = Get-SPSolution "$FileName" -ErrorAction SilentlyContinue if ($solution -ne $null){ if ($solution.Deployed -eq $true){ Write-Host "Solution already installed, uninstalling" -foreground $couleurAlerte if ($solution.ContainsWebApplicationResource) { Uninstall-SPSolution "$FileName" -AllWebApplications -Confirm:$Confirm -ErrorAction Stop } else { Uninstall-SPSolution "$FileName" -Confirm:$Confirm -ErrorAction Stop } WaitForDeploymentJob -SolutionName $FileName } Write-Host "Removing solution" -foreground $couleurAlerte Remove-SPSolution "$FileName" -Confirm:$Confirm } Write-Host "Adding solution" -foreground $couleurStatut [void](Add-SPSolution $(Join-Path -path $wspFolder -childpath $FileName) -Confirm:$Confirm -ErrorAction Stop) Write-Host "Installing solution" -ForegroundColor $couleurStatut $solution = Get-SPSolution "$FileName" if ($solution.ContainsWebApplicationResource) { if ($WebApps -eq $null){ Write-Host "Solution deploys on specific web application(s)" -ForegroundColor $couleurStatut $WebApps = AskForMultipleWebApplicationUrl } foreach($webapp in $WebApps){ Write-Host "Deploying on "$webapp -ForegroundColor $couleurStatut Install-SPSolution -Identity "$FileName" -WebApplication $webapp -GACDeployment -Force:$true -Confirm:$Confirm -ErrorAction Stop WaitForDeploymentJob $FileName } } else { Install-SPSolution -Identity "$FileName" -GACDeployment -Force:$Force -Confirm:$Confirm WaitForDeploymentJob $FileName } } } #Retract, remove, add, deploy solution function RedeploySolutions { param( [string[]]$WebApps, [switch]$Confirm, [switch]$Force ) $files = get-childitem . *.wsp [int]$count = 0 foreach($file in $files){ if ($file -ne $null){ WriteDecoredLine -Message $file [bool]$continue = $true if ($Confirm -eq $true) { $do = Read-Host "Confirm " $file "? (Y/N)" if ($do -ne "Y") { $continue = $false } } if ($continue) { $solution = Get-SPSolution "$file" -ErrorAction SilentlyContinue if ($solution -ne $null){ if ($solution.Deployed -eq $true){ WriteDecoredMessage -Message "Solution already installed, uninstalling" if ($solution.ContainsWebApplicationResource) { Uninstall-SPSolution "$file" -AllWebApplications -Confirm:$Confirm -ErrorAction Stop } else { Uninstall-SPSolution "$file" -Confirm:$Confirm -ErrorAction Stop } WaitForDeploymentJob -SolutionName $file } WriteDecoredMessage -Message "Removing solution" Remove-SPSolution "$file" -Confirm:$Confirm } WWriteDecoredMessage -Message "Adding solution" [void](Add-SPSolution $(Resolve-Path $file) -Confirm:$Confirm -ErrorAction Stop) WriteDecoredMessage -Message "Installing solution" $solution = Get-SPSolution "$file" if ($solution.ContainsWebApplicationResource) { if ($WebApps -eq $null){ Write-Host "This solution deploys on specific web application(s)" -ForegroundColor $couleurStatut $WebApps = AskForMultipleWebApplicationUrl } foreach($webapp in $WebApps){ Write-Host "Deploying on "$webapp -ForegroundColor $couleurStatut Install-SPSolution -Identity "$file" -WebApplication $webapp -GACDeployment -Force:$Force -Confirm:$Confirm -ErrorAction Stop WaitForDeploymentJob $file $count = $count + 1 } } else { Install-SPSolution -Identity "$file" -GACDeployment -Force:$Force -Confirm:$Confirm WaitForDeploymentJob $file $count = $count + 1 } } } } } #restart owstimer function RestartTimerService{ [array]$servers= Get-SPServer | ? {$_.Role -eq "Application"} foreach ($server in $servers) { Write-Host "Restarting Timer Service on $server" $Service = Get-WmiObject -Computer $server.name Win32_Service -Filter "Name='SPTimerV4'" if ($Service -ne $null) { $Service.InvokeMethod('StopService',$null) Start-Sleep -s 8 $service.InvokeMethod('StartService',$null) Start-Sleep -s 5 Write-Host -ForegroundColor $couleurOK "Timer Job successfully restarted on $server" } else { Write-Host -ForegroundColor $couleurNOK "Could not find SharePoint Timer Service on $server" } } } ########################################################################## # CREATE AND DELETE SITES ########################################################################## # delete site if exists function DeleteSiteIfExists{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [switch]$Verbose ) $Site = Get-SPSite $SiteUrl -ErrorAction SilentlyContinue if ($Site -ne $null){ if ($Verbose){ Write-Host "Removing existing site" -ForegroundColor $couleurAlerte } Remove-SPSite $Site -Confirm:$false -ErrorAction Stop $Site.Dispose() } } #create site collection function CreateSite{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$Template = $(throw "Parameter [Template] required"), [string]$SiteOwner = $(throw "Parameter [SiteOwner] required"), [string]$SiteName = $(throw "Parameter [SiteName] required"), [int]$Language = 1036, [switch]$Verbose ) DeleteSiteIfExists -SiteUrl $SiteUrl -Verbose:$Verbose Write-Host "Creating site" -ForegroundColor $couleurStatut [void](New-SPSite -Url $SiteUrl -OwnerAlias $SiteOwner -Language $Language -Name $SiteName -Template $Template -ErrorAction Stop) } #create publiscshing site collection function CreatePublishingTestSite{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$SiteOwner = $(throw "Parameter [SiteOwner] required") ) $Site = Get-SPSite $SiteUrl -ErrorAction SilentlyContinue if ($Site -eq $null){ Write-Host "Creating publishing site for tests..." -ForegroundColor $couleurStatut -NoNewline [void](New-SPSite -Url $SiteUrl -OwnerAlias $SiteOwner -Language 1033 -Name "TEST" -Template "BLANKINTERNET#0" -ErrorAction Stop) WriteOK } } ########################################################################## # SERVICES ADMINISTRATION ############################################################################# function AddAccountAsTermStoreAdministrator{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$Account = $(throw "Parameter [Account] required") ) $site = Get-SPSite $SiteUrl $session = Get-SPTaxonomySession -Site $SiteUrl $termstore = $session.TermStores[0] $termstore.AddTermStoreAdministrator($Account) $termstore.CommitAll() $site.Dispose() } #add application pool account to termstore function AddAppPoolAccountAsTermStoreAdministrator{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required") ) Write-Host "Adding application pool account as term store administrator..." -ForegroundColor $couleurStatut -NoNewline $site = Get-SPSite $SiteUrl $account = $site.WebApplication.ApplicationPool.Username AddAccountAsTermStoreAdministrator -SiteUrl $site.Url -Account $account WriteOK } function AddCurrentAccountAsTermStoreAdministrator{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required") ) $account = [Environment]::UserDomainName + "\" + [Environment]::UserName Write-Host "Adding current account " $account " as term store administrator..." -ForegroundColor $couleurStatut -NoNewline AddAccountAsTermStoreAdministrator -SiteUrl $SiteUrl -Account $account WriteOK } #add admin account to userprofile service application function AddAccountAsUserProfileAdministrator{ param( [string]$Account = $(throw "Parameter [Account] required") ) $claimType = "http://schemas.microsoft.com/sharepoint/2009/08/claims/userlogonname" $claimValue = $Account $claim = New-Object Microsoft.SharePoint.Administration.Claims.SPClaim($claimType, $claimValue, "http://www.w3.org/2001/XMLSchema#string", [Microsoft.SharePoint.Administration.Claims.SPOriginalIssuers]::Format("Windows")) [void]$claim.ToEncodedString() $permission = [Microsoft.SharePoint.Administration.AccessControl.SPIisWebServiceApplicationRights]"FullControl" $SPAclAccessRule = [Type]"Microsoft.SharePoint.Administration.AccessControl.SPAclAccessRule``1" $specificSPAclAccessRule = $SPAclAccessRule.MakeGenericType([Type]"Microsoft.SharePoint.Administration.AccessControl.SPIisWebServiceApplicationRights") $ctor = $SpecificSPAclAccessRule.GetConstructor(@([Type]"Microsoft.SharePoint.Administration.Claims.SPClaim",[Type]"Microsoft.SharePoint.Administration.AccessControl.SPIisWebServiceApplicationRights")) $accessRule = $ctor.Invoke(@([Microsoft.SharePoint.Administration.Claims.SPClaim]$claim, $permission)) $ups = Get-SPServiceApplication | ? { $_.TypeName -eq 'User Profile Service Application' } $ups | ForEach-Object{ $accessControl = $_.GetAccessControl() $accessControl.AddAccessRule($accessRule) $_.SetAccessControl($accessControl) $security = $_.GetAdministrationAccessControl() $spCentralAdminRights = [Microsoft.SharePoint.Administration.AccessControl.SPCentralAdministrationRights] $aclAccessRule = $spAclAccessRule.MakeGenericType($spCentralAdminRights) $actualAccessRule = New-Object($AclAccessRule) $claim, "FullControl" $security.AddAccessRule($actualAccessRule) $_.SetAdministrationAccessControl($security) $_.Update() } } #add account as administrator on userprofil service application function AddAppPoolAccountAsUserProfileAdministrator{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required") ) Write-Host "Adding application pool account as user profile service administrator..." -ForegroundColor $couleurStatut -NoNewline $site = Get-SPSite $SiteUrl $account = $site.WebApplication.ApplicationPool.Username AddAccountAsUserProfileAdministrator -Account $account WriteOK } #add current account to userprofile function AddCurrentAccountAsUserProfileAdministrator{ Write-Host "Adding current account as user profile service administrator..." -ForegroundColor $couleurStatut -NoNewline AddAccountAsUserProfileAdministrator -Account ([Environment]::UserDomainName + "\" + [Environment]::UserName) WriteOK } #Enlève le compte voulu des arministrateurs du term store function RemoveAccountFromTermStoreAdministrators{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$Account = $(throw "Parameter [Account] required") ) $site = Get-SPSite $SiteUrl $session = Get-SPTaxonomySession -Site $SiteUrl $termstore = $session.TermStores[0] $termstore.DeleteTermStoreAdministrator($Account) $termstore.CommitAll() $site.Dispose() WriteOK } #Remove application pool account from termstore function RemoveAppPoolAccountFromTermStoreAdministrators{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required") ) Write-Host "Removing application pool account from term store administrators..." -ForegroundColor $couleurStatut -NoNewline $site = Get-SPSite $SiteUrl RemoveAccountFromTermStoreAdministrators -SiteUrl $SiteUrl -Account $site.WebApplication.ApplicationPool.Username WriteOK } #set current term store service as default function SetMetadataServiceAsDefaultColumnTermSetsStorageLocation{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required") ) Write-Host "Setting up managed metadata service connection to allow managed navigation..." -ForegroundColor $couleurStatut -NoNewline $site = Get-SPSite $SiteUrl $metadataServiceProxy = $site.WebApplication.ServiceApplicationProxyGroup.DefaultProxies | Where {$_.TypeName -eq "Managed Metadata Service Connection"} $metadataServiceProxy = $metadataServiceProxy[0] $metadataServiceProxy.Properties["IsDefaultSiteCollectionTaxonomy"] = $true $metadataServiceProxy.Update() WriteOK } #Ajaa user properties section function AddUserPropertiesSection{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$SectionName = $(throw "Parameter [SectionName] required"), [string]$SectionDisplayName = $(throw "Parameter [SectionDisplayName] required") ) [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles") $sps = Get-SPSite $SiteUrl $serviceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($sps) $userProfileConfigManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($serviceContext) $userProfilePropertyManager = $userProfileConfigManager.ProfilePropertyManager $userProfileCoreProperties = $userProfilePropertyManager.GetCoreProperties() $userProfileTypePropertyManager = $userProfilePropertyManager.GetProfileTypeProperties([Microsoft.Office.Server.UserProfiles.ProfileType]::User) $userProfileSubtypeManager = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::Get($serviceContext) $userProfileSubType = $userProfileSubtypeManager.GetProfileSubtype([Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::GetDefaultProfileName([Microsoft.Office.Server.UserProfiles.ProfileType]::User)) $userProfileSubTypePropertyManager = $userProfileSubType.Properties $session = $userProfileCoreProperties.GetSectionByName($SectionName) if ($session -eq $null){ Write-Host "Ajout de la section " $SectionName "..." -NoNewline $section = userProfileCoreProperties.Create($true) $section.Name = $SectionName $section.DisplayName = $SectionDisplayName $userProfileCoreProperties.Add($section) $sectionTypeProperty = $userProfileTypePropertyManager.Create($section) $userProfileTypePropertyManager.Add($sectionTypeProperty) $sectionSubtypeProperty = $userProfileSubTypePropertyManager.Create($sectionTypeProperty) $userProfileSubTypePropertyManager.Add($sectionSubtypeProperty) WriteOK } else{ Write-Host "La section " $SectionName " existe déjà" -ForegroundColor $couleurAlerte } $sps.Dispose() } #Add property to user profile function AddUserProperty{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$PropertyName = $(throw "Parameter [PropertyName] required"), [string]$PropertyDisplayName = $(throw "Parameter [PropertyDisplayName] required"), [string]$Privacy = $(throw "Parameter [Privacy] required"), [switch]$UserEditable, [switch]$Visible, [switch]$Multivalued, [switch]$UserOverridePrivacy, [string]$Type = $(throw "Parameter [Type] required"), [int]$Length ) [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles") $sps = Get-SPSite $SiteUrl $serviceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($sps) $userProfileConfigManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($serviceContext) $userProfilePropertyManager = $userProfileConfigManager.ProfilePropertyManager $userProfileCoreProperties = $userProfilePropertyManager.GetCoreProperties() $userProfileTypePropertyManager = $userProfilePropertyManager.GetProfileTypeProperties([Microsoft.Office.Server.UserProfiles.ProfileType]::User) $userProfileSubtypeManager = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::Get($serviceContext) $userProfileSubType = $userProfileSubtypeManager.GetProfileSubtype([Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::GetDefaultProfileName([Microsoft.Office.Server.UserProfiles.ProfileType]::User)) $userProfileSubTypePropertyManager = $userProfileSubType.Properties $property = $userProfileCoreProperties.GetPropertyByName($PropertyName) if ($property -eq $null){ Write-Host "Ajout de la propriété " $PropertyName "..." -Nonewline $property = $userProfileCoreProperties.Create($false) $property.Name = $PropertyName $property.DisplayName = $PropertyDisplayName $property.Type = $Type if ($Length -ne 0){ $property.Length = $Length } $property.IsMultivalued = $Multivalued $userProfileCoreProperties.Add($property) $sectionTypeProperty = $userProfileTypePropertyManager.Create($property) $sectionTypeProperty.IsVisibleOnViewer = $Visible $sectionTypeProperty.IsVisibleOnEditor = $Visible $userProfileTypePropertyManager.Add($sectionTypeProperty) $sectionSubtypeProperty = $userProfileSubTypePropertyManager.Create($sectionTypeProperty) $sectionSubtypeProperty.IsUserEditable = $UserEditable $sectionSubtypeProperty.DefaultPrivacy = $Privacy $sectionSubtypeProperty.UserOverridePrivacy = $UserOverridePrivacy $userProfileSubTypePropertyManager.Add($sectionSubtypeProperty) WriteOK } else{ Write-Host "La propriété " $PropertyName " existe déjà" -ForegroundColor $couleurAlerte } $sps.Dispose() } #add myme type to webapplicationr function AddMimeTypeToWebApplication{ param( [string]$WebAppUrl = $(throw "Parameter [WebAppUrl] required"), [string]$MimeType = $(thow "Parameter [MimeType] required") ) $webapp = Get-SPWebApplication $WebAppUrl if($webApp.AllowedInlineDownloadedMimeTypes -notcontains $MimeType) { Write-Host "add mymetype" $MimeType "..." -Nonewline $webApp.AllowedInlineDownloadedMimeTypes.Add($MimeType) $webApp.Update() WriteOK }else{ Write-Host "mimetype " $MimeType " already exist" -ForegroundColor $couleurAlerte } } #Change WebApplication List Throttling function ChangeWebApplicationListThrottling{ param( [string]$WebAppUrl = $(throw "Parameter [WebAppUrl] required"), [int]$Number = $(throw "Parameter [Number] required") ) Write-Host "Changing list throttling to " $Number " for " $WebAppUrl $webapp = Get-SPWebApplication $WebAppUrl $webapp.MaxQueryLookupFields = $Number $webapp.Update() } ########################################################################## # VALIDATIONS ########################################################################## #Chec kMetadataService Exists function CheckMetadataServiceExists{ param( [string]$WebAppUrl = $(throw "Parameter [WebAppUrl] required") ) Write-Host "Managed metadata service existance..." -ForegroundColor $couleurStatut -NoNewline $app = Get-SPWebApplication $WebAppUrl $metadataService = $app.ServiceApplicationProxyGroup.DefaultProxies | Where {$_.TypeName -eq "Managed Metadata Service Connection"} if ($metadataService -eq $null){ throw "Managed metadata service does not exist" } WriteOK } #Chec UserProfile Service Exists function CheckUserProfileServiceExists{ param( [string]$WebAppUrl = $(throw "Parameter [WebAppUrl] required") ) Write-Host "userprofil existance..." -ForegroundColor $couleurStatut -NoNewline $app = Get-SPWebApplication $WebAppUrl $userprofileService = $app.ServiceApplicationProxyGroup.DefaultProxies | Where {$_.TypeName -eq "User Profile Service Application Proxy"} if ($userprofileService -eq $null){ throw "upserprofil service does not exist" } WriteOK } #Check MySite Host Url function CheckMySiteHostUrl{ param( [string]$SiteUrl = $(throw "Parameter [SiteUrl] required"), [string]$MySiteUrl = $(throw "Parameter [MySiteUrl] required") ) Write-Host "User profile service related my site host url..." -ForegroundColor $couleurStatut -NoNewline $servicecontext = Get-SPServiceContext ($SiteUrl) $upm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($servicecontext) if ($upm.MySiteHostUrl -eq $null -or $upm.MySiteHostUrl -eq ""){ throw "My site host url not filled" } $MySiteHost = Get-SPSite $upm.MySiteHostUrl -ErrorAction SilentlyContinue if ($MySiteHost -eq $null){ throw "My site host url does not correspond to an existing site" } $MySite = Get-SPSite $MySiteUrl if ($MySiteHost.Url -ne $MySite.Url){ throw "My site host url does not correspond to a my site host" } $MySiteHost.Dispose() $MySite.Dispose() WriteOK } #Upgrade Site Feature function UpgradeSiteFeature{ param( [string]$FeatureGuid = $(throw "Parameter [FeatureGuid] required"), [Microsoft.SharePoint.SPSite]$Site = $(throw "Parameter [Site] required") ) $Guid = New-Object -TypeName System.Guid -ArgumentList $FeatureGuid Write-Host "Upgrading feature $FeatureGuid" -ForegroundColor $couleurStatut Write-Host "Old version" -ForegroundColor $couleurStatut $Site.QueryFeatures($Guid,$true) | Format-Table Version $Site.QueryFeatures($Guid,$true) | Foreach{$_.Upgrade($true)} Write-Host "New version" -ForegroundColor $couleurStatut $Site.QueryFeatures($Guid,$false) | Format-Table Version } ########################################################################## # USER management ########################################################################## function AddUserToGroup{ param( [string]$Url = $(throw "Parameter [Url] required"), [string]$GroupName = $(throw "Parameter [GroupName] required"), [string]$LoginUser = $(throw "Parameter [LoginUser] required") ) #$site = Get-SPSite $Url $web = Get-SPWeb $Url $group= $web.SiteGroups[$GroupName] if($group -ne $null) { try{ $group.AddUser($web.EnsureUser($LoginUser)) Write-Host "Added user '$LoginUser' to the group '$GroupName' in the site '$($web.ServerRelativeUrl)'" -ForegroundColor $couleurOK } catch { Write-Host "Error: Failed to add the users to the group '$GroupName'." -ForegroundColor $couleurNOK } } else { Write-Host "Error: the group '$GroupName' doesn't exist in the site '$($web.ServerRelativeUrl)'." -ForegroundColor $couleurNOK } $web.Dispose() } function EnsureLogDirectory([string] $logFilePath) { try { $global:logActivated = $false if(-not [string]::IsNullOrEmpty($logFilePath)) { $global:logActivated = $true $global:logFilePath = $logFilePath $logDirectoryPath = [System.IO.Path]::GetDirectoryName($logFilePath) $logDirectory = [System.IO.Directory]::CreateDirectory("$logDirectoryPath") } } catch { $exception = $error[0].Exception.ToString() Write-Host " An eeor occured on log file creation '$logFilePath' :`n$exception" -foregroundcolor Red Log "An eeor occured on log file creation '$logFilePath' :`n$exception" "ERROR" exit 0 } } function Log([string]$message, [string]$messageType, [boolean]$writehost=$true) { try { if($global:logActivated) { if([string]::IsNullOrEmpty($messageType)) { $message | Out-File $global:logFilePath -append } else { $currentDate = Get-Date "[$currentDate] [$messageType] $message" | Out-File $global:logFilePath -append } } else { if($messageType.ToLower -eq "error") { Write-Host $message -foregroundcolor Red return; } if($messageType.ToLower -eq "info") { Write-Host $message return; } if($writehost){ Write-Host $message } } } catch { $exception = $error[0].Exception.ToString() Write-Host " an error occured while writing in log file '$global:logFilePath' :`n$exception" -foregroundcolor Red exit 0 } } function GetConfigurationParamater([string] $parameterPath, [bool] $showErrorIfNotExists) { try { WriteInfo "=> get configuration parameter '$parameterPath'." $configurationParameter = $script:configurationFileDocument.SelectSingleNode("$parameterPath") if($configurationParameter -ne $null) { return $configurationParameter.InnerText } else { if($showErrorIfNotExists) { WriteError "configuration parameter '$parameterPath' does not exist " "ERROR" return $null } else { WriteError "configuration parameter '$parameterPath' does not exist " "ERROR" return $null } } } catch { $exception = $error[0].Exception.ToString() WriteError "=> An error occured on loading configuration file '$parameterPath' :`n$exception" exit } } function GetConfigurationParamaterNoOuput([string] $parameterPath, [bool] $showErrorIfNotExists) { try { $configurationParameter = $script:configurationFileDocument.SelectSingleNode("$parameterPath") if($configurationParameter -ne $null) { return $configurationParameter.InnerText } } catch { $exception = $error[0].Exception.ToString() WriteError "=> An error occured on loading configuration file '$parameterPath' :`n$exception" exit } } #region ExecutePostActions function ExecutePostActions() { try { WriteInfo "Check features to activate / Deactive post deployment." if($script:BlockingError -ne "") { WriteError "an error occured before post actions. '$script:BlockingError'" exit 1 } $postActions = $script:configurationFileDocument.SelectSingleNode("/Parameters/PostActions") if($postActions.ChildNodes.Count -gt 0) { WriteInfo "execute actions post deployment." $features = $script:configurationFileDocument.SelectNodes("/Parameters/PostActions/Features/Feature") foreach($feature in $features) { $featureId = $feature.Attributes.ItemOf("Id").Value $featureAction = $feature.Attributes.ItemOf("Action").Value $featureTargetUrl = $feature.Attributes.ItemOf("Url").Value $featureScope = $feature.Attributes.ItemOf("Scope").Value $featureTitle = $feature.Attributes.ItemOf("Title").Value switch($featureAction.ToLower()) { "activate" { ActivateFeature $featureId $featureTargetUrl $featureScope $featureTitle break } "deactivate" { DeactivateFeature $featureId $featureTargetUrl $featureScope $featureTitle break } } WriteInfo "$featureAction $featureId on $featureTargetUrl." } } else { WriteInfo "no feature activity in post action. $exception" return } } catch { $exception = $error[0].Exception.ToString() WriteError "an error occured while executing post actions :`n$exception" $script:etatInstallation = "ERROR" $global:CurrentStep = $global:CurrentStep + 1 throw } } #endregion ExecutePostActions #region ActivateFeature function ActivateFeature([string] $featureId, [string] $targetUrl, [string] $scope, [string] $title) { try { if([string]::IsNullOrEmpty($targetUrl)) { WriteInfo "enable feature'$title' '$featureId'." $feature = Enable-SPFeature $featureId -ErrorAction Stop WriteInfo "Feature '$featureId' as been activated." } else { WriteInfo "Activate Feature '$title' '$featureId' scope:'$scope' on url '$targetUrl'." WriteInfo "targetUrl: $targetUrl - featureID:$featureId" $currentfeatureWebApplication = $null $currentfeatureSite = $null $currentfeatureWeb = $null $theScope = $scope if($scope -eq "Site"){ $currentfeatureSite = Get-SPFeature -Site $targetUrl | Where {$_.ID -eq "$featureId"} } if($scope -eq "Web"){ $currentfeatureWeb = Get-SPFeature -Web $targetUrl | Where {$_.ID -eq "$featureId"} } if($scope -eq "WebApplication"){ $currentfeatureWebApplication = Get-SPFeature -WebApplication $targetUrl | Where {$_.ID -eq "$featureId"} } if($currentfeatureSite -ne $null -or $currentfeatureWeb -ne $null -or $currentfeatureWebApplication -ne $null) { $feature = Disable-SPFeature $featureId -Url $targetUrl -Confirm:$false -ErrorAction Stop $theScope = $feature.Scope WriteInfo "feature '$title' '$featureId' has been deactivated on '$targetUrl' scope '$theScope'." } $feature = Enable-SPFeature $featureId -Url $targetUrl -ErrorAction Stop WriteInfo "feature '$title' '$featureId' has been activated on '$targetUrl' scope '$theScope'." } } catch { $exception = $error[0].Exception.ToString() WriteError "an error occured while activating feature'$title' '$featureId' :`n$exception" $global:CurrentStep = $global:CurrentStep + 1 throw } } #endregion ActivateFeature #region DeactivateFeature function DeactivateFeature([string] $featureId, [string] $targetUrl, [string] $scope, [string] $title) { try { if([string]::IsNullOrEmpty($targetUrl)) { WriteInfo "Disable feature '$title' '$featureId'." $feature = Disable-SPFeature $featureId -Confirm:$false -ErrorAction Stop WriteInfo "feature '$featureId' has been disabled" } else { WriteInfo "Disable featureé '$title' '$featureId' scope:'$scope' sur l'url '$targetUrl'." # $targetWeb = Get-SPWeb $targetUrl $currentfeatureWebApplication = $null $currentfeatureSite = $null $currentfeatureWeb = $null $theScope = $scope if($scope -eq "Site"){ $currentfeatureSite = Get-SPFeature -Site $targetUrl | Where {$_.ID -eq "$featureId"} } if($scope -eq "Web"){ $currentfeatureWeb = Get-SPFeature -Web $targetUrl | Where {$_.ID -eq "$featureId"} } if($scope -eq "WebApplication"){ $currentfeatureWebApplication = Get-SPFeature -WebApplication $targetUrl | Where {$_.ID -eq "$featureId"} } if($currentfeatureSite -ne $null -or $currentfeatureWeb -ne $null -or $currentfeatureWebApplication -ne $null) { $feature = Disable-SPFeature $featureId -Url $targetUrl -Confirm:$false -ErrorAction Stop WriteInfo "feature '$title''$featureId' has been disabled '$targetUrl' scope '$theScope'." } else { WriteInfo "feature '$title''$featureId' was not enabled on '$targetUrl' scope '$theScope'." } # $targetWeb.Dispose() } } catch { $exception = $error[0].Exception.ToString() WriteError "an error occured while desabling'$title' '$featureId' :`n$exception" $global:CurrentStep = $global:CurrentStep + 1 throw } } #endregion DeactivateFeature function ScheduleJobs() { try { # WriteInfo "check jobs to plan." $currentFolder = (Get-Item -Path ".\" -Verbose).FullName $jobsFolderPath = [System.IO.Path]::Combine($currentFolder, "Jobs") $jobsFolder = New-Object System.IO.DirectoryInfo $jobsFolderPath if($jobsFolder.Exists) { $jobsDefinitionFile = $jobsFolder.GetFiles("*.config") if($jobsDefinitionFile.Count -eq 0) { WriteInfo "no job definition file configuration has been found." } elseif($jobsDefinitionFile.Count -gt 1) { WriteError "more than one job defition congiuration has been found." exit } else { $jobsDefinitionFileName = $jobsDefinitionFile[0].FullName WriteInfo "plan job file '$jobsDefinitionFileName'." .\PlanJobs -Fichier $jobsDefinitionFileName -Log $logFilePath if($LASTEXITCODE -eq 0) { WriteError "an error occured while creating job'$jobsDefinitionFileName'." exit } else { WriteInfo "job from configuration '$jobsDefinitionFileName' ended." } } } else { WriteInfo "Folder '$jobsFolderPath' does not exist." } } catch { $exception = $error[0].Exception.ToString() WriteError "an error occured on job planification :`n$exception" "ERROR" $script:etatInstallation = "ERROR" throw } } ########################################################################## # TAXONOMY ########################################################################## function GetTaxoFieldValue([Microsoft.SharePoint.SPWeb]$Web,[Microsoft.SharePoint.Taxonomy.TaxonomyField]$Field,[string]$Value){ $taxoSession = Get-SPTaxonomySession -Site $Web.Site $termStore = $taxoSession.TermStores[$Field.SspId] $termSet = $termStore.GetTermSet($Field.TermSetId) $termcollection = $termSet.GetTerms($value,$true) if ($termCollection.Count -gt 0){ $term = $termCollection[0] } else{ $term = $termSet.CreateTerm($Value,1033) $termStore.CommitAll() } $taxoValue = New-Object Microsoft.SharePoint.Taxonomy.TaxonomyFieldValue($Field) $taxoValue.TermGuid = $term.Id.ToString() $taxoValue.Label = $term.Name return $taxoValue }