Hey Everyone so I am able to set the sharepoint sites sensitivity labels in my tenant by doing them individually using the following commands:
# Get the label (required ExchangeOnlineManagement module)
Connect-IPPSSession -userprincipalname wise#redacted
$c = Get-Credential wise#redacted
Connect-SPOService -Url https://redacted-admin.sharepoint.com -Credential $c -ModernAuth:$true -AuthenticationUrl https://login.microsoftonline.com/organizations
Set-SPOSite -identity {site_url} -SensitivityLabel:'{GUID of sens label here}'
And now I am trying to set a default label for all sites that have not been manually set by users with the following code, but its throwing the "Site already has a sensitivity label" message, meaning the if statement isnt triggering when ran from a site in a variable???
# Get the label (required ExchangeOnlineManagement module)
Connect-IPPSSession -userprincipalname wise#redacted
$c = Get-Credential wise#redacted
Connect-SPOService -Url https://redacted-admin.sharepoint.com -Credential $c -ModernAuth:$true -AuthenticationUrl https://login.microsoftonline.com/organizations
#Create a progress counter and fail counter
$count = 0
$fail = 0
#get all sites
write-host "Collecting site data" -ForegroundColor Yellow
$SiteCollections = Get-SPOSite -Limit All
write-host "Collecting site data - COMPLETED" -ForegroundColor Green
#get a count of total sites
$total = $SiteCollections.count
write-host "There are $total total sites." -ForegroundColor Green
foreach ($site in $SiteCollections){
$count++
try{
if ( $site.SensitivityLabel -eq '' ){
Set-SPOSite $site -SensitivityLabel:'{GUID}'
} else {
$label = $site.SensitivityLabel
Write-host "Site already has a sensitivity label: $label"
$site.Url | Out-File '.\Sites_already_labeled.txt' -Append
}
} catch {
$sitename = $site.Name
"Bad site: $sitename" | Out-File '.\Failed_change_sites.txt' -Append
$fail++
Write-Host "Failed site count = $fail" -ForegroundColor Blue
Write-Host "Failed site = $sitename" -ForegroundColor Blue
}
Write-Host "Processing Site $count of $total" -ForegroundColor Red
}
I have tested the if sens label = '' on singular sites and it does infact fufill the if statement so im completely lost.
Thanks ChatGPT!
It's likely that the issue is with the following line of code: if ( $site.SensitivityLabel -eq '' ). The SensitivityLabel property of a SharePoint Online site may not be an empty string when it has no label applied to it. Instead, it may be $null, so the if statement should be updated to if ( $site.SensitivityLabel -eq $null ).
I am trying to create a new list item in a SharePoint Online list using the Pnp.PowerShell Module in a PowerShell script. Here is my code and the output:
## ... urls and security creds removed...
Connect-PnPOnline -Url $km_site -ClientId $clientid -ClientSecret $secret -WarningAction Ignore
[Microsoft.SharePoint.Client.List]$projects_list = Get-PnPList "Projects"
Write-Host $projects_list.Title -ForegroundColor Green
$lci = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation -ArgumentList #()
[Microsoft.SharePoint.Client.ListItem]$new_item = $projects_list.AddItem($lci)
Write-Host $new_item.Id -ForegroundColor Cyan
$new_item["Title"] = $title
$new_item["Project_x0020_Code"] = $code
$new_item["_ExtendedDescription"] = $desc
$new_item["ContentTypeId"] = "0x010097F10B16E4516A4E80FC5C8FABF9BAC400AEEB05A0E486404FA588439EADC25541"
# Write-Host $new_item.FieldValues -ForegroundColor Cyan
$new_item.Update()
# $projects_list.Update()
Write-Host "Created!!" -ForegroundColor Yellow
Write-Host $new_item.Id -ForegroundColor Yellow
Output:
Projects
-1
Created!!
-1
The code matches what've seen in other online samples, but the list item isn't created, but it doesn't raise an error.
In my list, Title and Project Code are required and I am using a custom content type that I created in the Admin portal and then included in the 'Projects' list.
This was the solution that works.
Connect-PnPOnline -Url $km_site -ClientId $clientid -ClientSecret $secret -WarningAction Ignore
[Microsoft.SharePoint.Client.listItem]$list_item = Add-PnPListItem -List "Projects" -ContentType "Project Info" -Values #{"Title" = $title; "_ExtendedDescription"=$desc; "Project_x0020_Code"=$code}
I have a simple script that creates a Word Document and a PowerPoint document for staff that are sitting an exam where the files needed are pre loaded to a user area on a file share. The Word Document opens an creates the document header with the line of code
$Header = $Section.Headers.Item(1);
$Header.Range.Text = "$FirstName $SecondName $ID Activity 1";
PowerPoint is a bit more funnier and when you add a header it asks for dates. Is there a way to do this with powershell? We are printing them afterwards so would be a lot more benificial to have the variables that are in the CSV printed in the header of the document.
If this isn't doable is there a way to edit the first slide to have the variables in the first slide of the PowerPoint.
If anyone is able to look at the code or any ways of simplifying it, it would be massively appreiciated
The CSV is listed below and the full script is at the bottom :)
ID Four First Second
219999 9999 Tech Support
Have a good day
$Exams = Import-Csv "C:\\techtest.csv"
$fileserver = "C:\\ExamHomes\"
foreach ($User in $Exams)
{
$FirstName = $User.First
$SecondName = $User.Second
$ID = $User.ID
$FourID = $User.Four
$Time = "am"
$Date = "1511"
$Word = New-Object -ComObject Word.Application;
$Word.Visible = $false;
$Doc = $Word.Documents.Add();
$Section = $Doc.Sections.Item(1);
$Header = $Section.Headers.Item(1);
$Header.Range.Text = "$FirstName $SecondName $ID Activity 1";
$Doc.SaveAs("$fileserver\${date}${time}-${FourID}\Desktop\activity 1_${ID}_${FirstName}_${SecondName}.docx");
$Word.Quit()
Write-Host "File 'activity 1_${ID}_${FirstName}_${SecondName}.docx' for $FirstName $SecondName has been created and sent to the folder ${date}${time}-${FourID}" -BackgroundColor Black -ForegroundColor Cyan
add-type -assembly microsoft.office.interop.powerpoint
$Application = New-Object -ComObject powerpoint.application
$slideType = "microsoft.office.interop.powerpoint.ppSlideLayout" -as [type]
$presentation = $application.Presentations.add()
$presentation.SaveAs("$fileserver\${date}${time}-${FourID}\Desktop\activity 1_${ID}_${FirstName}_${SecondName}.pptx")
$presentation.close()
Stop-Process -name POWERPNT -Force
Write-Host "File 'activity 1_${ID}_${FirstName}_${SecondName}.pptx' for $FirstName $SecondName has been created and sent to the folder ${date}${time}-${FourID}" -BackgroundColor Black -ForegroundColor Cyan
}
Write-Host "All Staff have successfully had their document deployed for the exam" -BackgroundColor Black -ForegroundColor Red
Headers are only available for Notes Master and Handout Master objects
But you can add a Footer on a slide.
Add-Type -AssemblyName microsoft.office.interop.powerpoint
$Application = New-Object -ComObject powerpoint.application
$presentation = $application.Presentations.add()
$slide = $presentation.Slides.Add(1, [Microsoft.Office.Interop.PowerPoint.PpSlideLayout]::ppLayoutTitle)
$slide.Shapes.Title.TextFrame.TextRange.Text = "My Title"
$slide.Shapes(2).TextFrame.TextRange.Text = "My SubTitle"
$slide.HeadersFooters.Footer.Visible = $true
$slide.HeadersFooters.Footer.Text = "My Name"
You can use some Text on the DateAndTime HeaderFooter object like this:
$slide.HeadersFooters.DateAndTime.Visible = $true
$slide.HeadersFooters.DateAndTime.UseFormat = $true
$slide.HeadersFooters.DateAndTime.Format = [Microsoft.Office.Interop.PowerPoint.PpDateTimeFormat]::ppDateTimeFigureOut
$slide.HeadersFooters.DateAndTime.Text = "Coucou"
EDIT: SLIDE MASTER
In fact this can be defined on the SlideMaster so that every Slide inherit the values from the footer, pagenumber or datetime.
This is defined at the presentation level. So depending what you want do it on the SlideMaster or on any Slide you create. Probably a Slide may override the values from the SlideMaster.
$presentation.SlideMaster.HeadersFooters.SlideNumber.Visible = $true
$presentation.SlideMaster.HeadersFooters.Footer.Visible = $true
$presentation.SlideMaster.HeadersFooters.Footer.Text = "My Name"
$presentation.SlideMaster.HeadersFooters.DateAndTime.Visible = $true
$presentation.SlideMaster.HeadersFooters.DateAndTime.UseFormat = $true
$presentation.SlideMaster.HeadersFooters.DateAndTime.Format = [Microsoft.Office.Interop.PowerPoint.PpDateTimeFormat]::ppDateTimeFigureOut
$presentation.SlideMaster.HeadersFooters.DateAndTime.Text = "Something"
I am trying to add an existing site column to the SharePoint list. I have tried the following code:
#Setup the context
$listTitle = "VersionCleanup2247"
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
$clientContext.Load($clientContext.Web);
$clientContext.Load($clientContext.Web.Lists);
$clientContext.ExecuteQuery()
$list = $clientContext.Web.lists | where{$_.Title -eq $listTitle}
if($list)
{
Write-Host "list is already there. Loading the existing list."
$list = $clientContext.Web.lists.GetByTitle($listTitle)
$clientContext.Load($list);
$clientContext.ExecuteQuery()
Write-Host "Loaded" -ForegroundColor Green
}
Write-Host "Loading the default view of list"
$defaultView = $list.defaultView
$clientContext.Load($defaultView)
$clientContext.ExecuteQuery()
Write-Host "Loaded" -ForegroundColor Green
Write-Host "Loading the available field in the current site"
$siteColumns = $clientContext.Web.Fields
$clientContext.Load($siteColumns)
$clientContext.ExecuteQuery()
Write-Host "Loaded" -ForegroundColor Green
Write-host "adding comments fields from available site columns to the list"
$colName = $siteColumns | Where {$_.InternalName -eq "_Comments"}
$clientContext.Load($colName)
$clientContext.ExecuteQuery()
$list.Fields.Add($colName)
$list.Update()
$clientContext.ExecuteQuery()
$defaultView.ViewFields.Add("Comments")
$defaultView.Update()
$clientContext.ExecuteQuery()
Here I am trying to add a column whose internal name is _Commentsand Display name is Comments. But while adding it I am getting the following error:
Error info! Exception calling "ExecuteQuery" with "0" argument(s): "Field or property "DescriptionResource" does not exist."
Following dll files I am loading:
Add-Type -Path "c:\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Microsoft.SharePoint.Client.Runtime.dll"
And I have the full admin access on the site. Any suggestions would be appreciated. Thanks!
I'm deploying apps using Import-SPAppPackage and Install-SPApp. I'd like to be able to use Set-AppPrincipalPermission to set permissions but I can't get it working.
I'm uploading a SharePoint-hosted app to SharePoint using the PowerShell cmdlets Import-SPAppPackage and Install-SPApp. This is working fine for SharePoint-hosted apps that do not require additional permissions.
However, one app needs read access to the site, so this is declared in the manifest. And it works fine when run through Visual Studio - on first launch, it correctly asks to trust the app for read access to the site.
When I add this app via PowerShell, it has no opportunity to ask. The install continues without problems, but then the app doesn't work. (It fails with a permissions problem, which is absolutely the correct behavour since the permissions haven't yet been granted.)
I can fix the permissions by going to the Site Contents, clicking on the '...' for the problem app, choosing 'Permissions' and then clicking the link that says 'If there's something wrong with the app's permissions, click here to trust it again'.
But I really want to just be able to do the whole deployment via PowerShell.
The Set-AppPrincipalPermission cmdlet should allow me to set the permissions, but I can't get it to work. Specifically, I can't get a handle on the app principal that was automatically created when the app was deployed, so I can't pass this app principal to Set-AppPrincipalPermission.
The app principal has a name of the form 'i:0i.t|ms.sp.int|#' and it is listed on /_layouts/15/appprincipals.aspx. When I use Get-SPAppPrincipal with it, all I get is:
Get-SPAppPrincipal : The app principal could not be found.
I haven't seen any examples of using Get-SPAppPrincipal for any SharePoint-hosted apps - they all seem to be for provider-hosted apps. They also all seem to just use an app principal ID built from the client ID and the realm ID, but my SharePoint-hosted app doesn't have a client ID.
Is it possible to get the app principal of a SharePoint-hosted app and use it to set the permissions via PowerShell? Am I doing something wrong, or is there another approach?
I struggled the same problem like you and finally found an answer in these two blogs:
Blog with a nice Install, Update and Delete Script
Here is a nice post about "pressing" the "Trust It" Button via PowerShell Link
And because I know how lazy programmers like me are, feel free to use this merged script to Install Apps:
param
(
[string]$Web = $(throw '- Need a SharePoint web site URL (e.g. "http://portal.contoso.com/")'),
[string]$Source = "ObjectModel"
)
Write-Host -ForegroundColor White "-------------------"
Write-Host -ForegroundColor White "| App Installer |"
Write-Host -ForegroundColor White "-------------------"
Write-Host -ForegroundColor White "- "
#Global vars
$AppPackageName = "App.app";
#Loads powershell settings
Write-Host -ForegroundColor White "- Load Powershell context.."
$0 = $myInvocation.MyCommand.Definition
$dp0 = [System.IO.Path]::GetDirectoryName($0)
#Loads the SharePoint snapin
Write-Host -ForegroundColor White "- Load SharePoint context.."
$ver = $host | select version
if ($ver.Version.Major -gt 1) {$host.Runspace.ThreadOptions = "ReuseThread"}
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
Add-PSSnapin "Microsoft.SharePoint.PowerShell";
}
[void][System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
#Imports the App package
Write-Host -ForegroundColor White "- Import app package '$AppPackageName'..."
$appPath = "C:\Projects\App\App\bin\Debug\app.publish\1.0.0.0" + "\" + $AppPackageName;
if ($Source.Equals("ObjectModel", [System.StringComparison]::InvariantCultureIgnoreCase)) {
$sourceApp = ([microsoft.sharepoint.administration.spappsource]::ObjectModel);
}
elseif ($Source.Equals("Marketplace", [System.StringComparison]::InvariantCultureIgnoreCase)) {
$sourceApp = ([microsoft.sharepoint.administration.spappsource]::Marketplace);
}
elseif ($Source.Equals("CorporateCatalog", [System.StringComparison]::InvariantCultureIgnoreCase)) {
$sourceApp = ([microsoft.sharepoint.administration.spappsource]::CorporateCatalog);
}
elseif ($Source.Equals("DeveloperSite", [System.StringComparison]::InvariantCultureIgnoreCase)) {
$sourceApp = ([microsoft.sharepoint.administration.spappsource]::DeveloperSite);
}
elseif ($Source.Equals("RemoteObjectModel", [System.StringComparison]::InvariantCultureIgnoreCase)) {
$sourceApp = ([microsoft.sharepoint.administration.spappsource]::RemoteObjectModel);
}
$spapp = Import-SPAppPackage -Path "$appPath" -Site $Web -Source $sourceApp -Confirm:$false -ErrorAction SilentlyContinue -ErrorVariable err;
if ($err -or ($spapp -eq $null))
{
Write-Host -ForegroundColor Yellow "- An error occured during app import !"
throw $err;
}
Write-Host -ForegroundColor White "- Package imported with success."
#Installs the App
Write-Host -ForegroundColor White "- Install the APP in web site..."
$app = Install-SPApp -Web $Web -Identity $spapp -Confirm:$false -ErrorAction SilentlyContinue -ErrorVariable err;
if ($err -or ($app -eq $null)) {
Write-Host -ForegroundColor Yellow "- An error occured during app installation !"
throw $err;
}
$AppName = $app.Title;
Write-Host -ForegroundColor White "- App '$AppName' registered, please wait during installation..."
$appInstance = Get-SPAppInstance -Web $Web | where-object {$_.Title -eq $AppName};
$counter = 1;
$maximum = 150;
$sleeptime = 2;
Write-Host -ForegroundColor White "- Please wait..." -NoNewline;
$url = "$($Web)_layouts/15/appinv.aspx?AppInstanceId={$($appInstance.Id)}"
$ie = New-Object -com internetexplorer.application
try
{
$ie.visible=$true
$ie.navigate2($url)
while ($ie.busy)
{
sleep -milliseconds 60
}
$trustButton = $ie.Document.getElementById("ctl00_PlaceHolderMain_BtnAllow")
$trustButton.click()
sleep -Seconds 1
Write-Host "App was trusted successfully!"
}
catch
{
throw ("Error Trusting App");
}
while (($appInstance.Status -eq ([Microsoft.SharePoint.Administration.SPAppInstanceStatus]::Installing)) -and ($counter -lt $maximum))
{
Write-Host -ForegroundColor White "." -NoNewline;
sleep $sleeptime;
$counter++;
$appInstance = Get-SPAppInstance -Web $Web | where-object {$_.Title -eq $AppName}
}
Write-Host -ForegroundColor White ".";
if ($appInstance.Status -eq [Microsoft.SharePoint.Administration.SPAppInstanceStatus]::Installed) {
Write-Host -ForegroundColor White "- The App was successfully installed.";
$appUrl = $appInstance.AppWebFullUrl;
Write-Host -ForegroundColor White "- The App is now available at '$appUrl'.";
Write-Host -ForegroundColor White "- (Don't forget to add app host name in your host file if necessary...).";
Write-Host -ForegroundColor White "- "
}
else {
Write-Host -ForegroundColor Yellow "- An unknown error has occured during app installation. Read SharePoint log for more information.";
}
Figured out a way other than using IE.
Basically just using powershell to call SPAppPrincipalPermissionsManager.AddAppPrincipalToWeb
$rootUrl = "https://ur-sp.com"
$urlSiteName = "ur-site"
$web = Get-SPWeb "$rootUrl/$urlSiteName"
$appPrincipalManager = [Microsoft.SharePoint.SPAppPrincipalManager]::GetManager($web)
$applicationEndPointAuthorities = new-object System.Collections.Generic.List[string]
$applicationEndPointAuthorities.Add("$rootUrl/$urlSiteName");
$symmetricKey = New-Object System.Security.SecureString;
$datetimeNow = [System.DateTime]::Now
$credential = [Microsoft.SharePoint.SPAppPrincipalCredential]::CreateFromSymmetricKey($symmetricKey,$datetimeNow,$datetimeNow)
$creationParameters =New-Object Microsoft.SharePoint.SPExternalAppPrincipalCreationParameters($appid,$appFriendlyName,$applicationEndPointAuthorities,$credential)
$appPrincipal = $appPrincipalManager.CreateAppPrincipal($creationParameters)
$appPrincipalPermissionsManager = New-Object -TypeName
Microsoft.SharePoint.SPAppPrincipalPermissionsManager -ArgumentList $web
$r = $appPrincipalPermissionsManager.AddAppPrincipalToWeb($appPrincipal, 3)
3 is of SPAppPrincipalPermissionKind enum, and I don't think its value really matters.
This will do the full trust part via powershell:
$targetWeb = Get-SPSite "http://dev.my.com"
$clientID = "82ea34fc-31ba-4e93-b89a-aa41b023fa7e"
$authRealm = Get-SPAuthenticationRealm -ServiceContext $targetWeb
$AppIdentifier = $clientID + "#" + $authRealm
$appPrincipal = Get-SPAppPrincipal -Site $targetWeb.RootWeb -NameIdentifier $AppIdentifier
Set-SPAppPrincipalPermission -Site $targetWeb.RootWeb -AppPrincipal $appPrincipal -Scope SiteCollection -Right FullControl
More info here:
http://lixuan0125.wordpress.com/2013/11/18/register-and-install-app-through-powershell/