Skip to content

Commit b323911

Browse files
committed
Sharepoint functions
1 parent 5b2fde3 commit b323911

4 files changed

Lines changed: 267 additions & 6 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function Get-CIPPSPOTenant {
2+
[CmdletBinding()]
3+
Param(
4+
[Parameter(Mandatory = $true)]
5+
[string]$TenantFilter,
6+
[string]$SharepointPrefix
7+
)
8+
9+
if (!$SharepointPrefix) {
10+
# get sharepoint admin site
11+
$tenantName = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/sites/root' -asApp $true -tenantid $TenantFilter).id.Split('.')[0]
12+
} else {
13+
$tenantName = $SharepointPrefix
14+
}
15+
$AdminUrl = "https://$($tenantName)-admin.sharepoint.com"
16+
17+
# Query tenant settings
18+
$XML = @'
19+
<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="SharePoint Online PowerShell (16.0.24908.0)" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="106" ObjectPathId="105" /><Query Id="107" ObjectPathId="105"><Query SelectAllProperties="true"><Properties /></Query></Query></Actions><ObjectPaths><Constructor Id="105" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>
20+
'@
21+
$AdditionalHeaders = @{
22+
'Accept' = 'application/json;odata=verbose'
23+
}
24+
$Results = New-GraphPostRequest -scope "$AdminURL/.default" -tenantid $TenantFilter -Uri "$AdminURL/_vti_bin/client.svc/ProcessQuery" -Type POST -Body $XML -ContentType 'text/xml' -AddedHeaders $AdditionalHeaders
25+
26+
$Results | Select-Object -Last 1 *, @{n = 'SharepointPrefix'; e = { $tenantName } }, @{n = 'TenantFilter'; e = { $TenantFilter } }
27+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
function New-CIPPSharepointSite {
2+
<#
3+
.SYNOPSIS
4+
Create a new SharePoint site
5+
6+
.DESCRIPTION
7+
Create a new SharePoint site using the Modern REST API
8+
9+
.PARAMETER SiteName
10+
The name of the site
11+
12+
.PARAMETER SiteDescription
13+
The description of the site
14+
15+
.PARAMETER SiteOwner
16+
The username of the site owner
17+
18+
.PARAMETER TemplateName
19+
The template to use for the site. Default is Communication
20+
21+
.PARAMETER SiteDesign
22+
The design to use for the site. Default is Topic
23+
24+
.PARAMETER WebTemplateExtensionId
25+
The web template extension ID to use
26+
27+
.PARAMETER SensitivityLabel
28+
The Purview sensitivity label to apply to the site
29+
30+
.PARAMETER TenantFilter
31+
The tenant associated with the site
32+
33+
#>
34+
[CmdletBinding(SupportsShouldProcess = $true)]
35+
Param(
36+
[Parameter(Mandatory = $true)]
37+
[string]$SiteName,
38+
39+
[Parameter(Mandatory = $true)]
40+
[string]$SiteDescription,
41+
42+
[Parameter(Mandatory = $true)]
43+
[string]$SiteOwner,
44+
45+
[Parameter(Mandatory = $false)]
46+
[ValidateSet('Communication', 'Team')]
47+
[string]$TemplateName = 'Communication',
48+
49+
[Parameter(Mandatory = $false)]
50+
[ValidateSet('Topic', 'Showcase', 'Blank', 'Custom')]
51+
[string]$SiteDesign = 'Showcase',
52+
53+
[Parameter(Mandatory = $false)]
54+
[ValidatePattern('(\{|\()?[A-Za-z0-9]{4}([A-Za-z0-9]{4}\-?){4}[A-Za-z0-9]{12}(\}|\()?')]
55+
[string]$WebTemplateExtensionId,
56+
57+
[Parameter(Mandatory = $false)]
58+
[ValidatePattern('(\{|\()?[A-Za-z0-9]{4}([A-Za-z0-9]{4}\-?){4}[A-Za-z0-9]{12}(\}|\()?')]
59+
[string]$SensitivityLabel,
60+
61+
[string]$Classification,
62+
63+
[Parameter(Mandatory = $true)]
64+
[string]$TenantFilter
65+
)
66+
$tenantName = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/sites/root' -asApp $true -tenantid $TenantFilter).id.Split('.')[0]
67+
$AdminUrl = "https://$($tenantName)-admin.sharepoint.com"
68+
$SitePath = $SiteName -replace ' ' -replace '[^A-Za-z0-9-]'
69+
$SiteUrl = "https://$tenantName.sharepoint.com/sites/$SitePath"
70+
71+
72+
73+
74+
switch ($TemplateName) {
75+
'Communication' {
76+
$WebTemplate = 'SITEPAGEPUBLISHING#0'
77+
}
78+
'Team' {
79+
$WebTemplate = 'STS#0'
80+
}
81+
}
82+
83+
$WebTemplateExtensionId = '00000000-0000-0000-0000-000000000000'
84+
$DefaultSiteDesignIds = @( '96c933ac-3698-44c7-9f4a-5fd17d71af9e', '6142d2a0-63a5-4ba0-aede-d9fefca2c767', 'f6cc5403-0d63-442e-96c0-285923709ffc')
85+
86+
switch ($SiteDesign) {
87+
'Topic' {
88+
$SiteDesignId = '96c933ac-3698-44c7-9f4a-5fd17d71af9e'
89+
}
90+
'Showcase' {
91+
$SiteDesignId = '6142d2a0-63a5-4ba0-aede-d9fefca2c767'
92+
}
93+
'Blank' {
94+
$SiteDesignId = 'f6cc5403-0d63-442e-96c0-285923709ffc'
95+
}
96+
'Custom' {
97+
if ($WebTemplateExtensionId -match '^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$') {
98+
if ($WebTemplateExtensionId -notin $DefaultSiteDesignIds) {
99+
$WebTemplateExtensionId = $SiteDesign
100+
$SiteDesignId = '00000000-0000-0000-0000-000000000000'
101+
} else {
102+
$SiteDesignId = $WebTemplateExtensionId
103+
}
104+
} else {
105+
$SiteDesignId = '96c933ac-3698-44c7-9f4a-5fd17d71af9e'
106+
}
107+
}
108+
}
109+
110+
# Create the request body
111+
$Request = @{
112+
Title = $SiteName
113+
Url = $SiteUrl
114+
Lcid = 1033
115+
ShareByEmailEnabled = $false
116+
Description = $SiteDescription
117+
WebTemplate = $WebTemplate
118+
SiteDesignId = $SiteDesignId
119+
Owner = $SiteOwner
120+
WebTemplateExtensionId = $WebTemplateExtensionId
121+
}
122+
123+
# Set the sensitivity label if provided
124+
if ($SensitivityLabel) {
125+
$Request.SensitivityLabel = $SensitivityLabel
126+
}
127+
if ($Classification) {
128+
$Request.Classification = $Classification
129+
}
130+
131+
Write-Verbose ($Request | ConvertTo-Json -Compress -Depth 10)
132+
133+
$body = @{
134+
request = $Request
135+
}
136+
137+
# Create the site
138+
if ($PSCmdlet.ShouldProcess($SiteName, 'Create new SharePoint site')) {
139+
$AddedHeaders = @{
140+
'accept' = 'application/json;odata.metadata=none'
141+
'odata-version' = '4.0'
142+
}
143+
New-GraphPostRequest -scope "$AdminUrl/.default" -uri "$AdminUrl/_api/SPSiteManager/create" -Body ($body | ConvertTo-Json -Compress -Depth 10) -tenantid $TenantFilter -ContentType 'application/json' -AddedHeaders $AddedHeaders
144+
}
145+
}

Modules/CIPPCore/Public/SAMManifest.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
},
1313
"requiredResourceAccess": [
1414
{
15-
"resourceAppId": "aeb86249-8ea3-49e2-900b-54cc8e308f85",
16-
"resourceAccess": [
17-
{ "id": "fc946a4f-bc4d-413b-a090-b2c86113ec4f", "type": "Scope" }
18-
]
19-
},
15+
"resourceAppId": "aeb86249-8ea3-49e2-900b-54cc8e308f85",
16+
"resourceAccess": [
17+
{ "id": "fc946a4f-bc4d-413b-a090-b2c86113ec4f", "type": "Scope" }
18+
]
19+
},
2020
{
2121
"resourceAppId": "fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd",
2222
"resourceAccess": [
@@ -151,7 +151,8 @@
151151
{ "id": "b6890674-9dd5-4e42-bb15-5af07f541ae1", "type": "Role" },
152152
{ "id": "9e4862a5-b68f-479e-848a-4e07e25c9916", "type": "Scope" },
153153
{ "id": "bb6f654c-d7fd-4ae3-85c3-fc380934f515", "type": "Scope" },
154-
{ "id": "e0a7cdbb-08b0-4697-8264-0069786e9674", "type": "Scope" }
154+
{ "id": "e0a7cdbb-08b0-4697-8264-0069786e9674", "type": "Scope" },
155+
{ "id": "19da66cb-0fb0-4390-b071-ebc76a349482", "type": "Role" }
155156
]
156157
},
157158
{
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
function Set-CIPPSPOTenant {
2+
<#
3+
.SYNOPSIS
4+
Set Sharepoint Tenant properties
5+
6+
.DESCRIPTION
7+
Set Sharepoint Tenant properties via SPO API
8+
9+
.PARAMETER TenantFilter
10+
Tenant to apply settings to
11+
12+
.PARAMETER Identity
13+
Tenant Identity (Get from Get-CIPPSPOTenant)
14+
15+
.PARAMETER Properties
16+
Hashtable of tenant properties to change
17+
18+
.PARAMETER SharepointPrefix
19+
Prefix for the sharepoint tenant
20+
21+
.EXAMPLE
22+
$Properties = @{
23+
'EnableAIPIntegration' = $true
24+
}
25+
Get-CippSPOTenant -TenantFilter 'contoso.onmicrosoft.com' | Set-CIPPSPOTenant -Properties $Properties
26+
27+
.FUNCTIONALITY
28+
Internal
29+
30+
#>
31+
[CmdletBinding(SupportsShouldProcess = $true)]
32+
Param(
33+
[Parameter(ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
34+
[string]$TenantFilter,
35+
[Parameter(ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
36+
[Alias('_ObjectIdentity_')]
37+
[string]$Identity,
38+
[Parameter(Mandatory = $true)]
39+
[hashtable]$Properties,
40+
[Parameter(ValueFromPipelineByPropertyName = $true)]
41+
[string]$SharepointPrefix
42+
)
43+
44+
process {
45+
if (!$SharepointPrefix) {
46+
# get sharepoint admin site
47+
$tenantName = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/sites/root' -asApp $true -tenantid $TenantFilter).id.Split('.')[0]
48+
} else {
49+
$tenantName = $SharepointPrefix
50+
}
51+
$Identity = $Identity -replace "`n", '&#xA;'
52+
$AdminUrl = "https://$($tenantName)-admin.sharepoint.com"
53+
$AllowedTypes = @('Boolean', 'String', 'Int32')
54+
$SetProperty = [System.Collections.Generic.List[string]]::new()
55+
$x = 114
56+
foreach ($Property in $Properties.Keys) {
57+
# Get property type
58+
$PropertyType = $Properties[$Property].GetType().Name
59+
if ($PropertyType -in $AllowedTypes) {
60+
if ($PropertyType -eq 'Boolean') { $Properties[$Property] = $Properties[$Property].ToString().ToLower() }
61+
$xml = @"
62+
<SetProperty Id="$x" ObjectPathId="110" Name="$Property">
63+
<Parameter Type="Boolean">$($Properties[$Property])</Parameter>
64+
</SetProperty>
65+
"@
66+
$SetProperty.Add($xml)
67+
$x++
68+
}
69+
}
70+
71+
if (($SetProperty | Measure-Object).Count -eq 0) {
72+
Write-Error 'No valid properties found'
73+
return
74+
}
75+
76+
# Query tenant settings
77+
$XML = @"
78+
<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="SharePoint Online PowerShell (16.0.24908.0)" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions>$($SetProperty -join '')</Actions><ObjectPaths><Identity Id="110" Name="$Identity" /></ObjectPaths></Request>
79+
"@
80+
$AdditionalHeaders = @{
81+
'Accept' = 'application/json;odata=verbose'
82+
}
83+
84+
if ($PSCmdlet.ShouldProcess(($Properties.Keys -join ', '), 'Set Tenant Properties')) {
85+
New-GraphPostRequest -scope "$AdminURL/.default" -tenantid $TenantFilter -Uri "$AdminURL/_vti_bin/client.svc/ProcessQuery" -Type POST -Body $XML -ContentType 'text/xml' -AddedHeaders $AdditionalHeaders
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)