176 lines
6.6 KiB
PowerShell
176 lines
6.6 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$SiteUrl,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$ListTitle,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$ExpiryFieldInternalName,
|
|
|
|
[Guid]$FieldCustomizerComponentId = 'a555f4fc-d6a6-4421-8189-457449d9bbde',
|
|
|
|
[string]$ClassicScriptUrl = '~sitecollection/SiteAssets/ExpiryIndicator/ExpiryIndicatorClassic.js',
|
|
|
|
[switch]$SkipClassic
|
|
)
|
|
|
|
$isapiPath = Join-Path ([Environment]::GetFolderPath('CommonProgramFiles')) 'microsoft shared\Web Server Extensions\16\ISAPI'
|
|
Add-Type -Path (Join-Path $isapiPath 'Microsoft.SharePoint.Client.Runtime.dll')
|
|
Add-Type -Path (Join-Path $isapiPath 'Microsoft.SharePoint.Client.dll')
|
|
|
|
$context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
|
|
$context.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
|
|
|
|
try {
|
|
$list = $context.Web.Lists.GetByTitle($ListTitle)
|
|
$field = $list.Fields.GetByInternalNameOrTitle($ExpiryFieldInternalName)
|
|
$rootWeb = $context.Site.RootWeb
|
|
$customActions = $list.UserCustomActions
|
|
$webCustomActions = $context.Web.UserCustomActions
|
|
$context.Load($list)
|
|
$context.Load($field)
|
|
$context.Load($context.Web)
|
|
$context.Load($rootWeb)
|
|
$context.Load($rootWeb.AllProperties)
|
|
$context.Load($customActions)
|
|
$context.Load($webCustomActions)
|
|
$context.ExecuteQuery()
|
|
|
|
if ($field.InternalName -ne $ExpiryFieldInternalName) {
|
|
Write-Warning "Das Feld wurde über seinen Anzeigenamen gefunden. Verwende künftig den internen Namen '$($field.InternalName)'."
|
|
}
|
|
|
|
$alreadyBound = $field.ClientSideComponentId -eq $FieldCustomizerComponentId
|
|
$field.ClientSideComponentId = $FieldCustomizerComponentId
|
|
if (-not $alreadyBound -or [string]::IsNullOrWhiteSpace($field.ClientSideComponentProperties)) {
|
|
$field.ClientSideComponentProperties = ([ordered]@{
|
|
schemaVersion = 2
|
|
expiryField = $field.InternalName
|
|
inheritSiteDefaults = $true
|
|
} | ConvertTo-Json -Compress)
|
|
}
|
|
$field.Update()
|
|
|
|
$descriptorKey = 'PortalSettings.Solutions.ExpiryIndicator'
|
|
$bindingsKey = 'PortalSettings.ExpiryIndicator.Bindings'
|
|
$rootWeb.AllProperties[$descriptorKey] = ([ordered]@{
|
|
key = 'ExpiryIndicator'
|
|
displayName = 'Expiry Indicator'
|
|
version = '2.1.0'
|
|
provider = 'expiryIndicator'
|
|
componentIds = @(
|
|
'a555f4fc-d6a6-4421-8189-457449d9bbde',
|
|
'cd58f5d9-ffc8-4df7-a910-3054842d7abf',
|
|
'95691218-bcb1-4fad-adda-02bb12014d15'
|
|
)
|
|
settingsScope = @('siteCollection', 'web', 'list')
|
|
} | ConvertTo-Json -Compress -Depth 5)
|
|
|
|
$bindings = @()
|
|
$existingBindingsJson = [string]$rootWeb.AllProperties[$bindingsKey]
|
|
if (-not [string]::IsNullOrWhiteSpace($existingBindingsJson)) {
|
|
try {
|
|
$bindings = @($existingBindingsJson | ConvertFrom-Json)
|
|
}
|
|
catch {
|
|
Write-Warning 'Das vorhandene ExpiryIndicator-Bindungsinventar war ungültig und wird neu aufgebaut.'
|
|
}
|
|
}
|
|
|
|
$webUrl = $context.Web.Url.TrimEnd('/')
|
|
$listId = $list.Id.ToString('D')
|
|
$bindings = @($bindings | Where-Object {
|
|
-not (
|
|
([string]$_.webUrl).TrimEnd('/').Equals($webUrl, [StringComparison]::OrdinalIgnoreCase) -and
|
|
([string]$_.listId).Equals($listId, [StringComparison]::OrdinalIgnoreCase)
|
|
)
|
|
})
|
|
$bindings += [ordered]@{
|
|
webUrl = $webUrl
|
|
listId = $listId
|
|
listTitle = $list.Title
|
|
fieldInternalName = $field.InternalName
|
|
fieldId = $field.Id.ToString('D')
|
|
}
|
|
$rootWeb.AllProperties[$bindingsKey] = (ConvertTo-Json -InputObject @($bindings) -Compress -Depth 5)
|
|
$rootWeb.Update()
|
|
|
|
# Remove old diagnostic registrations and make the V2 Classic
|
|
# registrations idempotent.
|
|
$customActions | Where-Object {
|
|
$_.Name -eq 'ExpiryIndicator.CommandSet' -or
|
|
$_.Name -eq 'ExpiryIndicator.Classic.ScriptLink' -or
|
|
$_.Name -eq 'ExpiryIndicator.Classic.Ribbon'
|
|
} | ForEach-Object {
|
|
$_.DeleteObject()
|
|
}
|
|
|
|
if (-not $SkipClassic) {
|
|
$webCustomActions | Where-Object {
|
|
$_.Name -eq 'ExpiryIndicator.Classic.ScriptLink'
|
|
} | ForEach-Object {
|
|
$_.DeleteObject()
|
|
}
|
|
}
|
|
|
|
$context.ExecuteQuery()
|
|
|
|
if (-not $SkipClassic) {
|
|
# SharePoint permits Location=ScriptLink only on Web/Site custom
|
|
# actions, not on List.UserCustomActions. The runtime detects the
|
|
# current list and its bound expiry field by itself.
|
|
$scriptAction = $context.Web.UserCustomActions.Add()
|
|
$scriptAction.Name = 'ExpiryIndicator.Classic.ScriptLink'
|
|
$scriptAction.Title = 'ExpiryIndicator Classic runtime'
|
|
$scriptAction.Location = 'ScriptLink'
|
|
$scriptAction.ScriptSrc = $ClassicScriptUrl
|
|
$scriptAction.Sequence = 650
|
|
$scriptAction.Update()
|
|
|
|
$ribbonLocation = if ($list.BaseType -eq [Microsoft.SharePoint.Client.BaseType]::DocumentLibrary) {
|
|
'Ribbon.Library.Actions.Controls._children'
|
|
}
|
|
else {
|
|
'Ribbon.List.Actions.Controls._children'
|
|
}
|
|
|
|
$ribbonXml = @"
|
|
<CommandUIExtension xmlns="http://schemas.microsoft.com/sharepoint/">
|
|
<CommandUIDefinitions>
|
|
<CommandUIDefinition Location="$ribbonLocation">
|
|
<Button Id="ExpiryIndicator.Classic.ExtendOneYear.Button"
|
|
Command="ExpiryIndicator.Classic.ExtendOneYear"
|
|
Sequence="90"
|
|
LabelText="Ablaufdatum +1 Jahr"
|
|
Description="Verlängert das Ablaufdatum der ausgewählten Elemente um ein Kalenderjahr."
|
|
TemplateAlias="o1" />
|
|
</CommandUIDefinition>
|
|
</CommandUIDefinitions>
|
|
<CommandUIHandlers>
|
|
<CommandUIHandler Command="ExpiryIndicator.Classic.ExtendOneYear"
|
|
CommandAction="javascript:ExpiryIndicatorClassic.extendSelected();"
|
|
EnabledScript="javascript:ExpiryIndicatorClassic.canExtend();" />
|
|
</CommandUIHandlers>
|
|
</CommandUIExtension>
|
|
"@
|
|
|
|
$ribbonAction = $list.UserCustomActions.Add()
|
|
$ribbonAction.Name = 'ExpiryIndicator.Classic.Ribbon'
|
|
$ribbonAction.Title = 'ExpiryIndicator Classic ribbon command'
|
|
$ribbonAction.Location = 'CommandUI.Ribbon'
|
|
$ribbonAction.CommandUIExtension = $ribbonXml
|
|
$ribbonAction.Sequence = 651
|
|
$ribbonAction.Update()
|
|
|
|
$context.ExecuteQuery()
|
|
Write-Host 'Classic-Ansicht: Web-ScriptLink und listenspezifischer Ribbon-Befehl wurden registriert.'
|
|
}
|
|
|
|
Write-Host "ExpiryIndicator wurde für '$($list.Title)' an '$($field.InternalName)' gebunden."
|
|
}
|
|
finally {
|
|
$context.Dispose()
|
|
}
|