DSCResources/MSFT_xSPUserProfileProperty/MSFT_xSPUserProfileProperty.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.string] $Name , [parameter(Mandatory = $false)] [ValidateSet("Present","Absent")] [System.string ] $Ensure , [parameter(Mandatory = $true)] [System.string] $UserProfileService , [parameter(Mandatory = $false)] [System.string] $DisplayName , [parameter(Mandatory = $false)] [ValidateSet("BigInteger", "Binary", "Boolean", "Date", "DateNoYear", "DateTime", "Email", "Float", "Guid", "HTML", "Integer", "Person", "String", "StringMultiValue", "TimeZone", "URL")] [System.string] $Type , [parameter(Mandatory = $false)] [System.string] $Description , [parameter(Mandatory = $false)] [ValidateSet("Mandatory", "Optin","Optout", "Disabled")] [System.string] $PolicySetting , [parameter(Mandatory = $false)] [ValidateSet("Public", "Contacts", "Organization", "Manager", "Private")] [System.string] $PrivacySetting , [parameter(Mandatory = $false)] [System.string] $MappingConnectionName , [parameter(Mandatory = $false)] [System.string] $MappingPropertyName , [parameter(Mandatory = $false)] [System.string] $MappingDirection , [parameter(Mandatory = $false)] [System.uint32] $Length , [parameter(Mandatory = $false)] [System.uint32] $DisplayOrder , [parameter(Mandatory = $false)] [System.Boolean] $IsEventLog , [parameter(Mandatory = $false)] [System.Boolean] $IsVisibleOnEditor , [parameter(Mandatory = $false)] [System.Boolean] $IsVisibleOnViewer , [parameter(Mandatory = $false)] [System.Boolean] $IsUserEditable , [parameter(Mandatory = $false)] [System.Boolean] $IsAlias , [parameter(Mandatory = $false)] [System.Boolean] $IsSearchable, [parameter(Mandatory = $false)] [System.Boolean] $UserOverridePrivacy , [parameter(Mandatory = $false)] [System.string] $TermStore , [parameter(Mandatory = $false)] [System.string] $TermGroup , [parameter(Mandatory = $false)] [System.string] $TermSet , [parameter(Mandatory = $false)] [System.Management.Automation.PSCredential] $InstallAccount ) Write-Verbose -Message "Getting user profile service application $Name" $result = Invoke-xSharePointCommand -Credential $InstallAccount -Arguments $PSBoundParameters -ScriptBlock { $params = $args[0] $upsa = Get-SPServiceApplication -Name $params.UserProfileService -ErrorAction SilentlyContinue if ($null -eq $upsa) { return $null } $caURL = (Get-SpWebApplication -IncludeCentralAdministration | ?{$_.IsAdministrationWebApplication -eq $true }).Url $context = Get-SPServiceContext -Site $caURL $userProfileConfigManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($context) $userProfileSubTypeManager = Get-xSharePointUserProfileSubTypeManager $context $userProfileSubType = $userProfileSubTypeManager.GetProfileSubtype("UserProfile") $userProfileProperty = $userProfileSubType.Properties.GetPropertyByName($params.Name) if($null -eq $userProfileProperty ){ return $null } $termSet = @{ TermSet = "" TermGroup ="" TermStore = "" } if($userProfileProperty.CoreProperty.TermSet -ne $null) { $termSet.TermSet = $userProfileProperty.CoreProperty.TermSet.Name $termSet.TermGroup = $userProfileProperty.CoreProperty.TermSet.Group.Name $termSet.TermStore = $userProfileProperty.CoreProperty.TermSet.TermStore.Name } $mapping = @{ ConectionName = "" PropertyName ="" Direction = "" } $syncConnection = $userProfileConfigManager.ConnectionManager | ? {$_.PropertyMapping.Item($params.Name) -ne $null} if($syncConnection -ne $null) { $currentMapping = $syncConnection.PropertyMapping.Item($params.Name) if($currentMapping -ne $null) { $mapping.Direction = "Import" $mapping.ConnectionName = $params.MappingConnectionName if($currentMapping.IsExport) { $mapping.Direction = "Export" } $mapping.PropertyName = $currentMapping.DataSourcePropertyName } } return @{ Name = $userProfileProperty.Name UserProfileServiceAppName = $params.UserProfileService DisplayName = $userProfileProperty.DisplayName Type = $userProfileProperty.CoreProperty.Type.GetTypeCode() Description = $userProfileProperty.Description PolicySetting = $userProfileProperty.PrivacyPolicy PrivacySetting = $userProfileProperty.DefaultPrivacy MappingConnectionName = $mapping.ConnectionName MappingPropertyName = $mapping.PropertyName MappingDirection = $Mapping.Direction Length = $userProfileProperty.CoreProperty.Length DisplayOrder =$userProfileProperty.DisplayOrder IsEventLog =$userProfileProperty.TypeProperty.IsEventLog IsVisibleOnEditor=$userProfileProperty.TypeProperty.IsVisibleOnEditor IsVisibleOnViewer =$userProfileProperty.TypeProperty.IsVisibleOnViewer IsUserEditable = $userProfileProperty.IsUserEditable IsAlias = $userProfileProperty.IsAlias IsSearchable = $userProfileProperty.CoreProperty.IsSearchable TermStore = $termSet.TermStore TermGroup = $termSet.TermGroup TermSet = $termSet.TermSet UserOverridePrivacy = $userProfileProperty.AllowPolicyOverride } } return $result } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.string ] $Name , [parameter(Mandatory = $false)] [ValidateSet("Present","Absent")] [System.string ] $Ensure , [parameter(Mandatory = $true)] [System.string ] $UserProfileService , [parameter(Mandatory = $false)] [System.string ] $DisplayName , [parameter(Mandatory = $false)] [ValidateSet("BigInteger", "Binary", "Boolean", "Date", "DateNoYear", "DateTime", "Email", "Float", "Guid", "HTML", "Integer", "Person", "String", "StringMultiValue", "TimeZone", "URL")][System.string ] $Type , [parameter(Mandatory = $false)] [System.string ] $Description , [parameter(Mandatory = $false)] [ValidateSet("Mandatory", "Optin","Optout", "Disabled")] [System.string ] $PolicySetting , [parameter(Mandatory = $false)] [ValidateSet("Public", "Contacts", "Organization", "Manager", "Private")] [System.string ] $PrivacySetting , [parameter(Mandatory = $false)] [System.string ] $MappingConnectionName , [parameter(Mandatory = $false)] [System.string ] $MappingPropertyName , [parameter(Mandatory = $false)] [System.string ] $MappingDirection , [parameter(Mandatory = $false)] [System.uint32] $Length , [parameter(Mandatory = $false)] [System.uint32] $DisplayOrder , [parameter(Mandatory = $false)] [System.Boolean] $IsEventLog , [parameter(Mandatory = $false)] [System.Boolean] $IsVisibleOnEditor , [parameter(Mandatory = $false)] [System.Boolean] $IsVisibleOnViewer , [parameter(Mandatory = $false)] [System.Boolean] $IsUserEditable , [parameter(Mandatory = $false)] [System.Boolean] $IsAlias , [parameter(Mandatory = $false)] [System.Boolean] $IsSearchable, [parameter(Mandatory = $false)] [System.Boolean] $UserOverridePrivacy , [parameter(Mandatory = $false)] [System.string ] $TermStore , [parameter(Mandatory = $false)] [System.string ] $TermGroup , [parameter(Mandatory = $false)] [System.string ] $TermSet , [parameter(Mandatory = $false)] [System.Management.Automation.PSCredential] $InstallAccount ) #note for integration test: CA can take a couple of minutes to notice the change. don't try refreshing properties page. go through from a fresh "flow" from Service apps page :) Write-Verbose -Message "Creating user profile property $Name" $test = $PSBoundParameters $result = Invoke-xSharePointCommand -Credential $InstallAccount -Arguments $test -ScriptBlock { $params = $args[0] #region Validating parameter combinations if( ($params.ContainsKey("TermSet") -or $params.ContainsKey("TermGroup") -or $params.ContainsKey("TermSet") ) -and ($params.ContainsKey("TermSet") -and $params.ContainsKey("TermGroup") -and $params.ContainsKey("TermSet") -eq $false ) ) { throw "You have to provide all 3 parameters Termset, TermGroup and TermStore when providing any of the 3." } #what if combination property type + termstore isn't possible? if($params.ContainsKey("TermSet") -and (@("string","stringmultivalue").Contains($params.Type.ToLower()) -eq $false) ){ throw "Only String and String Maultivalue can use Termsets" } #endregion #region setting up objects $ups = Get-SPServiceApplication -Name $params.UserProfileService -ErrorAction SilentlyContinue If ($null -eq $ups) { return $null } $caURL = (Get-SpWebApplication -IncludeCentralAdministration | ?{$_.IsAdministrationWebApplication -eq $true }).Url $context = Get-SPServiceContext $caURL $userProfileConfigManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($context) if($null -eq $userProfileConfigManager) { #if config manager returns when ups is available then isuee is permissions throw "account running process needs admin permissions on the user profile service application" } $coreProperties = $userProfileConfigManager.ProfilePropertyManager.GetCoreProperties() $userProfilePropertyManager = $userProfileConfigManager.ProfilePropertyManager $userProfileTypeProperties = $userProfilePropertyManager.GetProfileTypeProperties([Microsoft.Office.Server.UserProfiles.ProfileType]::User) $userProfileSubTypeManager = Get-xSharePointUserProfileSubTypeManager $context $userProfileSubType = $userProfileSubTypeManager.GetProfileSubtype("UserProfile") $userProfileSubTypeProperties = $userProfileSubType.Properties #endregion $userProfileProperty = $userProfileSubType.Properties.GetPropertyByName($params.Name) if($userProfileProperty -ne $null -and $userProfileProperty.CoreProperty.Type.GetTypeCode() -ne $params.Type ) { throw "Can't change property type. Current Type is $($userProfileProperty.CoreProperty.Type.GetTypeCode())" } #region retrieving term set $termSet =$null #Get-TermSet if ($params.ContainsKey("TermSet")) { $currentTermSet=$userProfileProperty.CoreProperty.TermSet; if($currentTermSet.Name -ne $params.TermSet -or $currentTermSet.Group.Name -ne $params.TermGroup -or $currentTermSet.TermStore.Name -ne $params.TermStore){ $session = new-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($caURL); $termStore = $session.TermStores[$params.TermStore]; if($termStore -eq $null) { throw "Term Store $($params.termStore) not found" } $group = $termStore.Groups[$params.TermGroup]; if($group -eq $null) { throw "Term Group $($params.termGroup) not found" } $termSet = $group.TermSets[$params.TermSet]; if($termSet -eq $null) { throw "Term Set $($params.termSet) not found" } } } #endregion #Ensure-Property $params if( $params.ContainsKey("Ensure") -and $params.Ensure -eq "Absent"){ if($userProfileProperty -ne $null) { $coreProperties.RemovePropertyByName($params.Name) return; } } elseif($userProfileProperty -eq $null){ #region creating property $coreProperty = $coreProperties.Create($false) $coreProperty.Name = $params.Name $coreProperty.DisplayName = $params.DisplayName Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $coreProperty -PropertyToSet "Length" -ParamsValue $params -ParamKey "Length" if($params.Type.ToLower() -eq "stringmultivalue") { $coreProperty.IsMultivalued =$true; } $coreProperty.Type = $params.Type if($termSet -ne $null){ $coreProperty.TermSet = $termSet } $CoreProperties.Add($coreProperty) $upTypeProperty = $userProfileTypeProperties.Create($coreProperty) $userProfileTypeProperties.Add($upTypeProperty) $upSubProperty = $userProfileSubTypeProperties.Create($UPTypeProperty) $userProfileSubTypeProperties.Add($upSubProperty) Sleep -Milliseconds 100 $userProfileProperty = $userProfileSubType.Properties.GetPropertyByName($params.Name) #return $userProfileProperty #endregion } #region setting up properties #update-property $userProfileProperty $params $termSet $coreProperty = $userProfileProperty.CoreProperty $userProfileTypeProperty = $userProfileProperty.TypeProperty Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $coreProperty -PropertyToSet "DisplayName" -ParamsValue $params -ParamKey "DisplayName" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $coreProperty -PropertyToSet "Description" -ParamsValue $params -ParamKey "Description" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileTypeProperty -PropertyToSet "IsVisibleOnViewer" -ParamsValue $params -ParamKey "IsVisibleOnViewer" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileTypeProperty -PropertyToSet "IsVisibleOnEditor" -ParamsValue $params -ParamKey "IsVisibleOnEditor" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileTypeProperty -PropertyToSet "IsEventLog" -ParamsValue $params -ParamKey "IsEventLog" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileProperty -PropertyToSet "DefaultPrivacy" -ParamsValue $params -ParamKey "PrivacySetting" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileProperty -PropertyToSet "PrivacyPolicy" -ParamsValue $params -ParamKey "PolicySetting" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileProperty -PropertyToSet "IsUserEditable" -ParamsValue $params -ParamKey "IsUserEditable" Set-xSharePointObjectPropertyIfValueExists -ObjectToSet $userProfileProperty -PropertyToSet "UserOverridePrivacy" -ParamsValue $params -ParamKey "UserOverridePrivacy" if($termSet -ne $null){ $coreProperty.TermSet = $termSet } #endregion $userProfileProperty.CoreProperty.Commit() $userProfileTypeProperty.Commit() $userProfileProperty.Commit() #/Ensure-Property #region display order # Set-DisplayOrder if($params.ContainsKey("DisplayOrder")) { $profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context) $profileManager.Properties.SetDisplayOrderByPropertyName($params.Name,$params.DisplayOrder) $profileManager.Properties.CommitDisplayOrder() } #endregion #region mapping #Set-Mapping if($params.ContainsKey("MappingConnectionName") -and $params.ContainsKey("MappingPropertyName")){ $syncConnection = $userProfileConfigManager.ConnectionManager | Where-Object { $_.DisplayName -eq $params.MappingConnectionName} if($null -eq $syncConnection ) { throw "connection not found" } $syncConnection = $userProfileConfigManager.ConnectionManager| Where-Object { $_.DisplayName -eq $params.MappingConnectionName} #$userProfileConfigManager.ConnectionManager[$params.MappingConnectionName] $currentMapping = $syncConnection.PropertyMapping.Item($params.Name) if($currentMapping -eq $null -or ($currentMapping.DataSourcePropertyName -ne $params.MappingPropertyName) -or ($currentMapping.IsImport -and $params.ContainsKey("MappingDirection") -and $params.MappingDirection -eq "Export") ){ if($currentMapping -ne $null ){ $currentMapping.Delete() #API allows updating, but UI doesn't do that. } $export = $params.ContainsKey("MappingDirection") -and $params.MappingDirection -eq "Export" if ($Connection.Type -eq "ActiveDirectoryImport"){ if($export){ throw "not implemented" }else{ $Connection.AddPropertyMapping($params.MappingPropertyName,$params.Name) $Connection.Update() } }else{ if ($export){ $syncConnection.PropertyMapping.AddNewExportMapping([Microsoft.Office.Server.UserProfiles.ProfileType]::User,$params.Name,$params.MappingPropertyName) }else{ $syncConnection.PropertyMapping.AddNewMapping([Microsoft.Office.Server.UserProfiles.ProfileType]::User,$params.Name,$params.MappingPropertyName) } } } } #endregion } return $result } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [System.string ] $Name , [parameter(Mandatory = $false)] [ValidateSet("Present","Absent")] [System.string ] $Ensure , [parameter(Mandatory = $true)] [System.string ] $UserProfileService , [parameter(Mandatory = $false)] [System.string ] $DisplayName , [parameter(Mandatory = $false)] [ValidateSet("BigInteger", "Binary", "Boolean", "Date", "DateNoYear", "DateTime", "Email", "Float", "Guid", "HTML", "Integer", "Person", "String", "StringMultiValue", "TimeZone", "URL")][System.string ] $Type , [parameter(Mandatory = $false)] [System.string ] $Description , [parameter(Mandatory = $false)] [ValidateSet("Mandatory","Optin","Optout","Disabled")] [System.string ] $PolicySetting , [parameter(Mandatory = $false)] [ValidateSet("Public","Contacts","Organization","Manager","Private")] [System.string ] $PrivacySetting , [parameter(Mandatory = $false)] [System.string ] $MappingConnectionName , [parameter(Mandatory = $false)] [System.string ] $MappingPropertyName , [parameter(Mandatory = $false)] [System.string ] $MappingDirection , [parameter(Mandatory = $false)] [System.uint32] $Length , [parameter(Mandatory = $false)] [System.uint32] $DisplayOrder , [parameter(Mandatory = $false)] [System.Boolean] $IsEventLog , [parameter(Mandatory = $false)] [System.Boolean] $IsVisibleOnEditor , [parameter(Mandatory = $false)] [System.Boolean] $IsVisibleOnViewer , [parameter(Mandatory = $false)] [System.Boolean] $IsUserEditable , [parameter(Mandatory = $false)] [System.Boolean] $IsAlias , [parameter(Mandatory = $false)] [System.Boolean] $IsSearchable, [parameter(Mandatory = $false)] [System.Boolean] $UserOverridePrivacy , [parameter(Mandatory = $false)] [System.string ] $TermStore , [parameter(Mandatory = $false)] [System.string ] $TermGroup , [parameter(Mandatory = $false)] [System.string ] $TermSet , [parameter(Mandatory = $false)] [System.Management.Automation.PSCredential] $InstallAccount ) $CurrentValues = Get-TargetResource @PSBoundParameters Write-Verbose -Message "Testing for user profile property $Name" if ($null -eq $CurrentValues) { return $false } return Test-xSharePointSpecificParameters -CurrentValues $CurrentValues -DesiredValues $PSBoundParameters -ValuesToCheck @("Name","DisplayName","Type", "Description", "PolicySetting", "PrivacySetting","MappingConnectionName","MappingPropertyName", "MappingDirection", "Length", "DisplayOrder", "IsEventLog", "IsVisibleOnEditor", "IsVisibleOnViewer","IsUserEditable", "IsAlias", "IsSearchabe", "UserOverridePrivacy", "TermGroup", "TermStore", "TermSet") } Export-ModuleMember -Function *-TargetResource |