powershell
870 TopicsUPDATE: Create Office 365 Groups with team sites from SharePoint home moving beyond First Release
We recently completed the worldwide rollout for Office 365 Groups getting full-powered SharePoint team sites at the end of January 2017. Our next step is to now bring the ability to create SharePoint team sites connected to Office 365 Groups from SharePoint home beyond First Release. This next phase of rollout will begin today, and is expected to reach all customers worldwide over the next month. We also wanted to share some of the additional capabilities we’ve added to group-connected team sites since we first began roll out to First Release. No matter where you create an Office 365 Group from – whether SharePoint, Outlook, Microsoft Teams, Yammer, or elsewhere – you consistently get the full collaborative power of a connected SharePoint Online team site among the other services groups provides (shared inbox, shared calendar, Planner plan, team notebook, and more). This move beyond First Release includes the capabilities described in our November blog post: Fast creation of sites connected to Office 365 Groups from the SharePoint home page Editable team site home pages that look great at your desk and on your phone Modern creation panels for new libraries and lists In-place navigation editing Site settings panels for editing site information and site permissions Modern page creation in classic sites Admin controls for team site creation The site permissions panel listed above has been enhanced to include options for adding members to the site’s Office 365 Group or simply sharing only the team site without providing access to other group resources. The panel is intended to provide simple permissions management, but also includes a link to ‘Advanced permission settings’ for site owners that have a need to do things like add custom SharePoint permissions & mappings. Note this panel also allows you to add users or groups to the ‘Site Visitors’ permissions group, so it is easy to provide read-only access to the site. All you need to do is add a new person or group via the ‘Invite people’ button, and then change their permission level to ‘Read’. The user or group’s permission level determines which permission group they appear under – those with ‘Read’ permission will appear in the ‘Site Visitors’ category. Managing group-connected team sites Since new team sites are connected to Office 365 Groups, managing them involves possible interactions with Office 365 Group settings in addition to those provided by SharePoint. Examples include settings that apply to groups such as whether group creation is allowed in the tenant, which users are permitted to create groups, usage guidelines URL or group classification labels. Once the group-connected site is created, management of the site is likewise split between Azure Active Directory (AAD) PowerShell cmdlets and the SharePoint Online Management Shell. Anything dealing with creation, deletion, un-delete (restore) or membership happens through AAD. SharePoint-specific management, such as storage quota and link sharing policies, take place using the SharePoint management tools. For governing modern site creation, this support page details the administrative controls, but is useful to summarize the relationship between a group’s policy settings and how the SharePoint ‘Create site’ experience behaves. By default, if group creation is enabled in the tenant, the ‘Create site’ command will appear on SharePoint home, and if a user is permitted to create groups they will get the site creation experience. If the user is *not* permitted to create groups, they will get the classic self service provisioning experience that results in the creation of a subsite. The table below describes how the combination of group and site creation settings work together: * The current user is considered to have group creation permissions if the AAD property EnableGroupCreation is true, or it is false but the user is a member of the security group assigned to the GroupCreationAllowedId AAD property. ** Site creation is enabled via SharePoint Admin Center under Site creation settings: In addition to managing site creation, we are also enabling the SharePoint Online PowerShell cmdlets to administer modern, group-connected site collections. This means that modern team site collections can now be enumerated with the Get-SPOSite cmdlet with the following example: Get-SPOSite -Template GROUP#0 -IncludePersonalSite:$false Most parameters for these site collections can also be set using the Set-SPOSite cmdlet, with the exception of those that would result in breaking connection with their corresponding Office 365 Group (e.g. you cannot set the Owner property using this cmdlet – you would need to set the Group’s owners via AAD). Please refer to the respective documentation for each of the above cmdlets for additional details. For more information on using PowerShell to manage Office 365 Groups, this article may be helpful as well. What else is new? In addition to the above, this phase of the rollout includes a couple of previously unannounced capabilities. The first is a group membership management experience that lives in SharePoint itself. Now, when you click on the member count of the group in the site header, you will be presented with a new group membership panel that allows you to add members and change their roles between owners and members, or remove them outright. Users will no longer need to jump to Outlook to manage the group’s membership. The second is Content Type Hub syndication – modern sites can now consume content types that have been published from a central content type hub. We heard feedback that this is an important feature to enable, and we are including it in this rollout. As noted above, this rollout will take place over the course of a few weeks. We are very excited for you to take advantage of modern, connected team sites and look forward to any feedback or questions you may have. As always, please ask in a reply to this thread. Thanks, Tejas91KViews29likes76CommentsBuilding a SharePoint Online site from start to finish using OfficeDev PnP
I recently posted an article that discussed various deployment methods for SharePoint Online. In this article, I’ll share what worked for me in the past when creating entire sites from the ground up. You could leverage parts of it as needed to develop your process. Most of the process leverages PowerShell and the OfficeDev PnP PowerShell library. My process is broken down into the following three steps 1. Gather Requirements I always begin with identifying the needs of the users. Those include both configurations as well as information architecture. When I work with the users to define the information architecture, I prefer tools that are simple and efficient at gathering this data. For any information that is tabular in nature, I use Excel, while either Excel or an XML editor work well for hierarchical information. Excel is great because most business users have a basic understanding of how to fill in the sheets and use drop-down choices. The information architecture components I gather are: Taxonomy (Managed Metadata) Site Columns Content Types Lists & Libraries Views I like, to begin by defining the site taxonomy. SharePoint saves me some trouble here by providing me with an Excel structure that can be used to pass the information into the term store. As a first cut, all I need to do is select the worksheet and, if there are no errors, my term groups and term sets are created. You can get the template by navigating to https://<you rtenant>.sharepoint.com/sites/portal/_layouts/15/termstoremanager.aspx and selecting View a sample import file. I work with the users to fill in one of these files for each term group. Once I’ve defined the taxonomy, I move onto gathering information about the site columns and taxonomy columns. For the columns, I ask my users the following questions What should the name of the column be? How are the columns grouped? Is the column required? What type of data will the column hold? Is it a multiple choice column, and if yes, what are the choices for the column? For taxonomy columns, instead of asking for the type and options, I request the association of columns and term sets (based on what they’ve provided me earlier on). To reduce errors, I present the Required, Type and Multivalue columns as drop-downs for the user. I calculate the InternalName column by removing all spaces and special characters. I then add the GUID for each column. By providing the GUID, I make sure that for each deployment, the column can be referenced by any part of the site using the same ID. Next, I collect the Content Type data. Similar to the columns, I use an Excel document to capture the name, group, Field names, and whether they are required. However, because it’s hierarchical structure, I prefer to convert the content types to XML to simplify the code in PowerShell. After the content types are defined, I gather the lists, libraries, and views specifications. I’m capturing only specific settings about the lists, such as whether versioning and check-in/check-out should be enabled. However, it’s relatively easy to use PowerShell to modify additional information architecture settings. Just make sure that you capture the information in Excel and alter your import code to apply these changes. Capturing information about the configurations is a bit more involved as the available options for the configurations vary significantly. 2. Build Master Site Now that I’ve gathered all the necessary information from the users, I begin to build my master site. As the first step, I create the empty site and then apply to it all the configurations using specific PowerShell scripts that will match my requirements. The settings will include Turn features on/off Set the global and site navigation parameters Modify regional settings Configure search settings There are a lot more configurations available, but those are the usual suspects. Next, I tackle the information architecture by leveraging the Excel and XML files. Using a combination of OfficeDev PnP PowerShell functions and simple loops, I iterate through these files and build the site in the following sequence: Taxonomy Site columns and Taxonomy Columns Content Types Subsites Lists and libraries Views Once finished, I deploy a minimum amount of data for each site and taxonomy column for the search indexing. The sample data is utilized by SharePoint during its scheduled crawls and will enable the site to leverage search-driven configurations and customizations.At this point, my master site is ready to be exported into an OfficeDev PnP provisioning template. 3. Build Template Sites I can now take these templates and deploy them over and over to create new sites with the same configurations and content. Typically, I’ll use the template to create the QA and production environments. If I haven’t introduced any crazy customizations, then I could even apply the same templates in an on-premises environment. Finally, I deploy the content to the sites. NOTE: It is possible to create the provisioning templates manually, as they are simple XML files. However, I find it a bit risky as any errors could cause the entire template deployment process to fail. Benefits of using this approach I’m sure many readers can weigh into this article and provide their perspective and experiences on deploying sites. That’s great! By no means am I trying to imply that this method is better than others – it just works well for me. A few benefits that I’ve seen using this approach are: Gathering user requirements is easy. Depending on the comfort level of my users, they can even provide a lot of the information without my direct involvement. It’s very easy to make changes to the information architecture and redeploy a new master site By building the master site and using its template to create the QA and production environment, I’m in essence, testing the deployment process3.2KViews5likes2CommentsSyncing SharePoint Document Libraries on Non-Persistent Virtual Computers
I have searched for ways to "sync" a SPO Document Library, particularly a Teams Document Library, in a non-persistent VDI where you have access via Windows Explorer similarly to OneDrive. While I couldn't find anything directly to accomplish this, I did piece together a method that would achieve the goal with a PowerShell script and I wanted to share in case it helped others or could be improved upon by the community. Prereqs: OneDrive "per-machine install" installed on the gold image with on-demand enabled via GPO The first part of the script sets the vars needed for the SharePoint Document library. See https://docs.microsoft.com/en-us/onedrive/deploy-on-windows?redirectSourcePath=%252fen-us%252farticle%252fdeploy-the-new-onedrive-sync-client-in-an-enterprise-environment-3f3a511c-30c6-404a-98bf-76f95c519668 for information on how to find these values. $WebURL = "https://tenant.sharepoint.com/sites/" $SiteName = "SPOSite" $SiteID = "<thesiteid>" $ListID = "<thelistid>" After these values, I use a sleep timer to give time for all services to load before proceeding. Start-Sleep -s 20 Next is to query AD for the user's email address using Get-ADUser. The email address will be used by ODOpen to sync the library. $DomainServer = [System.Net.Dns]::GetHostByName($env:LOGONSERVER.Substring(2)).HostName $UserName = [Environment]::UserName $User = Get-ADUser -Server $DomainServer -Filter {SamAccountName -eq $UserName} -Properties * $UserEmail = $User.EmailAddress Next I use a "Do" loop to make sure OneDrive has started before trying to sync the library. Do{ $ODStatus = Get-Process onedrive -ErrorAction SilentlyContinue If ($ODStatus) { I add in another sleep timer to give OneDrive time to authenticate and start syncing the user's OneDrive. Start-Sleep -s 30 Next I set the path for the ODOpen command using the vars from earlier and start the process. $odopen = "odopen://sync/?siteId=" + $SiteID + "&webUrl=" + $webURL + $SiteName + "&listId=" + $ListID + "&userEmail=" + $User.EmailAddress + "&webTitle=" + $SiteName + " " Start-Process $odopen Lastly, I close out the Do loop } } Until ($ODStatus) Save the script to a network share accessible by users and use a GPO, or a product like VMware's DEM, to place a shortcut to the script in users' Startup folder. Complete script below. # Script for using OneDrive, with on-demand enabled, to sync SPO library at login # Create a shortcut to this script in the user's Startup folder # Target should be C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -File "\\server\share\SyncSPOSite.ps1" # Update variables below for the SPO library to sync. See this link for more info # https://docs.microsoft.com/en-us/onedrive/deploy-on-windows?redirectSourcePath=%252fen-us%252farticle%252fdeploy-the-new-onedrive-sync-client-in-an-enterprise-environment-3f3a511c-30c6-404a-98bf-76f95c519668 $WebURL = "https://tenant.sharepoint.com/sites/" $SiteName = "SPOSite" $SiteID = "<thesiteid>" $ListID = "<thelistid>" # Give Windows some time to load before getting the email address Start-Sleep -s 20 $DomainServer = [System.Net.Dns]::GetHostByName($env:LOGONSERVER.Substring(2)).HostName $UserName = [Environment]::UserName $User = Get-ADUser -Server $DomainServer -Filter {SamAccountName -eq $UserName} -Properties * $UserEmail = $User.EmailAddress # Use a "Do" loop to check to see if OneDrive process has started and continue to check until it does Do{ # Check to see if OneDrive is running $ODStatus = Get-Process onedrive -ErrorAction SilentlyContinue # If it is start the sync. If not, loopback and check again If ($ODStatus) { # Give OneDrive some time to start and authenticate before syncing library Start-Sleep -s 30 # set the path for odopen $odopen = "odopen://sync/?siteId=" + $SiteID + "&webUrl=" + $webURL + $SiteName + "&listId=" + $ListID + "&userEmail=" + $User.EmailAddress + "&webTitle=" + $SiteName + "" #Start the sync Start-Process $odopen } } Until ($ODStatus)34KViews5likes13CommentsHow to Properly Delete Custom Columns in SharePoint
SharePoint custom columns have been around for quite some time, but I’m finding that there’s still some confusion on how the various types are used, and more importantly how can you delete them. In this post, I’m hoping to shed some light on the topic. Custom columns form a part of your overall SharePoint Information Architecture. When properly set up, custom columns (or fields as sometimes referred to in SharePoint) are ideal for capturing metadata in a consistent way across various types of content. In SharePoint, you can create custom columns in one of two ways: Custom List Column Custom List columns are created directly within a list (or library). They can be accessed via the list and used to store information. Although quick to set up, one of the major drawbacks is that list columns are limited in scope to only the list in which you created them. You cannot leverage the site columns outside of the list. This reason alone can prevent such columns from being considered for scalable solutions where you would have to add the same columns to multiple lists or libraries throughout a SharePoint site. Custom Site Columns Custom Site columns, as their name suggests, are created at the site level. Unlike their List Column relatives, the Site columns are accessible throughout the entire site collection, where you can add them to any number of lists, libraries, and content types. When you change the Site column properties, you have the choice to propagate these changes to all instances where the Site column is in use. Deleting Custom Columns If you wish to remove a custom column, it’s important to understand your options and the ramification they have on your data as described below. Deleting a List Column As I’ve mentioned earlier, when you create a new column within a list or library (not selected from pre-existing site columns), the list owns the column, and the column is only accessible to the list. Therefore, you can easily delete it from the List Settings by selecting the column and then clicking the Delete button on the form. Keep in mind that once you delete the list column, you also lose any data associated with the column. Deleting a Site Column from a List A reference to the site column is added when you add a site column directly to a list. As mentioned above, whenever you change the site column, any instances that use it will change as well. In the example below, I’m showing a Date field that has been added directly to two lists. If you try and delete the Date site column, you will see a warning message similar to This site column will be removed and all list columns which were created from it will be permanently orphaned. Are you sure you want to delete this site column? What does orphaned mean? Well, think of the site column as being the parent that controls its children (the referencing site columns within the lists). They will behave as their parent does. When you delete the parent, then you are in essence converting the site columns within the lists into list columns that lose the relationship between them. In other words, each list will have its unique copy of the site column with all the same settings just before you deleted the site column. You cannot undo this change. Deleting a Site Column from a Content Type When you add a site column to a content type, you’re following better practices for your Information Architecture by encapsulating all required metadata into a reusable entity (content type) rather than dealing with the individual site columns in each list. On the flip side, deleting your site column now becomes a bit trickier. If you tried to remove a site column that is associated with a content type, you might have seen a message as Site columns which are included in content types cannot be deleted. Remove all references to this site column prior to deleting it. What you need to do in this case is remove the site column from each content type before removing it. But what do you do if you don’t know where it’s used? In this case, you can leverage PowerShell to help you get the answer you need. To find out what content types are using your site column, you first need to know the InternalName of your site column. You find it by going to the site column (Site Settings à Site Columns) and looking at the URL as depicted below. In my case, the field is called Date1. Now you can run the script below that is based on OfficeDev PnP to search all the content types in a site collection. The script lists all the content types that use the site column you wish to delete (NOTE: to run the code I’ve supplied below, you must install the OFficeDev PnP solution first from https://github.com/OfficeDev/PnP-PowerShell). Connect-Sponline -url "your_tenant_url" $fieldInternalName = "your_field" $web = Get-SPOWeb Write-Host "Searching for:" Write-Host "InternalName: $fieldInternalName" Write-Host Write-Host "Get Content Types" $cTypes = Get-SPOContentType | where {($_.Hidden -eq $False) -and ($_.Group -ne "_Hidden")} # Search through all the non-hidden content type and find which ones include the site column foreach($ct in $cTypes) { $fields = $ct.Fields $web.Context.Load($fields) $web.Context.ExecuteQuery() $field = ($fields | where {$_.InternalName -eq $fieldInternalName}) if ($field -ne $null) { Write-Host "Content Types: $($ct.Name)" Write-Host "Content Type ID: $($ct.ID)" } } The output will look something similar to the image below. Searching for: InternalName: Date1 Get Content Types Content Types: TestCT Content Type ID: 0x01010038A3F80D4105C845BDD6A523CB1CC969 Now you need to go to the Content Types (Site Settings à Site Content Types) and look for the content types by name. If you see any duplicates, compare the content type ID against the one listed in the URL. Just remember, removing the columns from the content type will delete the content of those columns. That’s it. Now you know what to look for when removing your custom columns. Good luck.51KViews5likes13CommentsSyncing Profile Pictures with Office 365 and Active Directory
Good Afternoon All, I wanted to share a script I came up with to help keep our active directory profile photos in sync with Office 365 and SharePoint Online, but first a little background on WHY I did this and how the script works along with a few caveats. I attached the script to this post, the code in the post is only for reference. Good Luck, Andrew Background: For some unknown reason, user profile photos were missing from Delve and SharePoint Online. They may have removed them on their own, but they still existed in our on-prem AD and we wanted to make sure they were in sync. We are all aware that the photo sync process is messy and rarely works well. One issue is that the photo sync only works on the initial sync of the photo, if we update an AD photo the changed photo never reflected in SharePoint (unsure if this changed yet). An admin could use the Set-UserPhoto cmd to update the photo but it would take anywhere from 24-72 hours to update in SharePoint, if it even did it at all. I create this script to synchronize the pictures from our Active Directory on prem to SPO and EXO (this covers most of the services we use atm that pull the profile picture). How it works: Rather than rely on 365 sync process, this script uses on prem AD as the source and manually updates the picture in both EXO and SPO. The script targets the 3 main OU's we are concerned with and creates an array of users that have the thumbnailPhoto attribute set in AD. It then exports the photo to a local drive Using an Image-Resize script, it resizes and properly names the 3 SPO thumbnails Runs the Set-UserPhoto cmd to for each user to set the photo in EXO (Delve, etc.) Uploads the 3 SPO thumbnails to the tenant User Profiles Library. Caveats: The SharePoint user profile should have a link defined in the "picture" attribute, I believe this is created by default regardless of whether the user had a picture synced previously or not. We kept the Picture Exchange Sync State attribute set to 1 just because, not sure if this is necessary. The script is NOT efficient but it works, I am SURE there are ways to make it a little smaller and more friendly to pop in some variables, I may update it later, but I wanted something that worked. There are definitely redundancies in repeating parts the script for each OU. I am going to post a sample for a single searchbase so it is easier to look at. This will be replaced with a variable in a future update so it is easier to manage. Script should be run using a global admin (although if you want you CAN individually permission the rights in EXO, SPO, and local AD.) It is EXTREMELY slow. Unfortunately the Set-UserPhoto cmd and really slow, nothing we can do about it. The SPO photo upload can be slow at times as well. This is not something I would do daily depending on the number of user accounts you have to sync. The local path to manage the images is hard coded atm to "C:\Scripts\Pics", create that directory or replace all instances of it in the script with your path (this will be fixed in an update to the script). Portions of the script were borrowed from the following. Resize-Image: https://gallery.technet.microsoft.com/scriptcenter/Resize-Image-A-PowerShell-3d26ef68 Upload Files to SP: https://www.c-sharpcorner.com/article/sharepoint-online-automation-o365-sharepoint-online-how-to-upload-your-files-r/ function Resize-Image { <# .SYNOPSIS Resize-Image resizes an image file .DESCRIPTION This function uses the native .NET API to resize an image file, and optionally save it to a file or display it on the screen. You can specify a scale or a new resolution for the new image. It supports the following image formats: BMP, GIF, JPEG, PNG, TIFF .EXAMPLE Resize-Image -InputFile "C:\kitten.jpg" -Display Resize the image by 50% and display it on the screen. .EXAMPLE Resize-Image -InputFile "C:\kitten.jpg" -Width 200 -Height 400 -Display Resize the image to a specific size and display it on the screen. .EXAMPLE Resize-Image -InputFile "C:\kitten.jpg" -Scale 30 -OutputFile "C:\kitten2.jpg" Resize the image to 30% of its original size and save it to a new file. .LINK Author: Patrick Lambert - http://dendory.net #> Param([Parameter(Mandatory=$true)][string]$InputFile, [string]$OutputFile, [int32]$Width, [int32]$Height, [int32]$Scale, [Switch]$Display) # Add System.Drawing assembly Add-Type -AssemblyName System.Drawing # Open image file $img = [System.Drawing.Image]::FromFile((Get-Item $InputFile)) # Define new resolution if($Width -gt 0) { [int32]$new_width = $Width } elseif($Scale -gt 0) { [int32]$new_width = $img.Width * ($Scale / 100) } else { [int32]$new_width = $img.Width / 2 } if($Height -gt 0) { [int32]$new_height = $Height } elseif($Scale -gt 0) { [int32]$new_height = $img.Height * ($Scale / 100) } else { [int32]$new_height = $img.Height / 2 } # Create empty canvas for the new image $img2 = New-Object System.Drawing.Bitmap($new_width, $new_height) # Draw new image on the empty canvas $graph = [System.Drawing.Graphics]::FromImage($img2) $graph.DrawImage($img, 0, 0, $new_width, $new_height) # Create window to display the new image if($Display) { Add-Type -AssemblyName System.Windows.Forms $win = New-Object Windows.Forms.Form $box = New-Object Windows.Forms.PictureBox $box.Width = $new_width $box.Height = $new_height $box.Image = $img2 $win.Controls.Add($box) $win.AutoSize = $true $win.ShowDialog() } # Save the image if($OutputFile -ne "") { $img2.Save($OutputFile); } } # Load SharePoint CSOM Assemblies Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll" Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll" # Connect to AD Import-Module ActiveDirectory # Connect to EXO $UserCredential = Get-Credential $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/?proxymethod=rps -Credential $UserCredential -Authentication Basic -AllowRedirection Import-PSSession $Session -DisableNameChecking # Connect to SPO $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserCredential.Username, $UserCredential.Password) # Bind to SPO site collection and Library $SiteURL = "https://YOURTENANT-my.sharepoint.com/" $DocLibName = "User Photos" $SubFolderName = "Profile Pictures" $Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL) $Context.Credentials = $Credentials $List = $Context.Web.Lists.GetByTitle($DocLibName) $FolderToBindTo = $List.RootFolder.Folders $Context.Load($List) $Context.Load($FolderToBindTo) $Context.ExecuteQuery() # Get all the employees with AD Pictures $user = Get-ADUser -filter * -Properties * -SearchBase 'DC=yourdomain,DC=com' | Select UserPrincipalName, thumbnailPhoto | Where-Object {$_.thumbnailPhoto -ne $NULL} # Export each users AD Pictures Write-Host "`nExporting User AD Pictures" foreach ($line in $user) { $upn = $line.UserPrincipalName Write-Host "`nProcessing" $line.UserPrincipalName -ForegroundColor Green $FileName = "C:\scripts\Pics\"+$line.UserPrincipalName+".jpg" Write-Host "Exporting AD Picture to" $FileName -ForegroundColor Yellow [System.Io.File]::WriteAllBytes($Filename, $line.thumbnailphoto) Write-Host "Creating SharePoint Photo Folder" -ForegroundColor Yellow New-Item -Path "C:\Scripts\Pics\" -Name $line.UserPrincipalName -ItemType "directory" -Force | Out-Null $FormattedName = $line.UserPrincipalName -replace "\.","_" -replace "@","_" Write-Host "Resizing Image for SharePoint" -ForegroundColor Yellow $NewFilePath = "C:\Scripts\Pics\" + $line.UserPrincipalName + "\" + $FormattedName + "_SThumb.jpg" Resize-Image -InputFile $FileName -Width 48 -Height 48 -Outputfile $NewFilePath Write-Host "Small Thumbnail Created" -ForegroundColor Cyan $NewFilePath = "C:\Scripts\Pics\" + $line.UserPrincipalName + "\" + $FormattedName + "_MThumb.jpg" Resize-Image -InputFile $FileName -Width 72 -Height 72 -Outputfile $NewFilePath Write-Host "Medium Thumbnail Created" -ForegroundColor Cyan $NewFilePath = "C:\Scripts\Pics\" + $line.UserPrincipalName + "\" + $FormattedName + "_LThumb.jpg" Resize-Image -InputFile $FileName -Width 96 -Height 96 -Outputfile $NewFilePath Write-Host "Large Thumbnail Created" -ForegroundColor Cyan } # Set each users 365 Photo using their exported AD photo Write-Host "`nSetting User 365 Photos" foreach ($line in $user) { Write-Host "`nProcessing" $line.UserPrincipalName -ForegroundColor Green Write-Host "Setting User Photo for" $line.UserPrincipalName -ForegroundColor yellow Set-UserPhoto -Identity $line.UserPrincipalName -PictureData ([System.IO.File]::ReadAllBytes("C:\scripts\Pics\"+$line.UserPrincipalName+".jpg")) -Confirm:$false write-host "Operation complete for" $line.UserPrincipalName -ForegroundColor green # Upload file to SPO Write-Host "Uploading pictures to SharePoint" -ForegroundColor Yellow $Folder = "C:\Scripts\Pics\" + $line.UserPrincipalName Write-Host "Source Picture Path is" $Folder -ForegroundColor Yellow $FolderToUpload = $FolderToBindTo | Where {$_.Name -eq $SubFolderName} Foreach($File in (dir $Folder -File)) { $FileStream = New-Object IO.FileStream($File.FullName, [System.IO.FileMode]::Open) $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation $FileCreationInfo.Overwrite = $true $FileCreationInfo.ContentStream = $FileStream $FileCreationInfo.URL = $File $Upload = $FolderToUpload.Files.Add($FileCreationInfo) $Context.Load($Upload) $Context.ExecuteQuery() } Write-Host "SharePoint Picture Upload Complete" -ForegroundColor Cyan Write-Host $line.UserPrincipalName "Photo Sync Complete" -ForegroundColor Green } #Close the EXO Session Remove-PSSession $Session42KViews4likes2CommentsNew SharePoint Provisioning Engine with PowerShell Module
I open sourced our SharePoint provisioning engine today along with three non-trivial samples. Still working on the docs. The wiki has only 33 pages at the moment, but please check it out anyway! https://github.com/InstantQuick/InstantQuick-SharePoint-Provisioning607Views4likes0CommentsHow to join the 2 SharePoint News World - Old Publishing site and Modern Teamsite
The SharePoint solution is changing since some years and Microsoft is moving fast to implement the Modern capabilities in all the SharePoint components. In the past, the Intranet site was built for most of the case, using the Publishing sites (technology existing since many years, probably SP 2003 for a large part), but today, the best solution could be to focus on the Communication sites associated with the modern sites. The problem is now with the existing Corporate sites running a huge solution based on the SharePoint Publishing: How to show my Publishing News into the Basic Office 365 SharePoint app (mobile or Web) ? A solution could be the usage of the "Repost Page". What is the Repost Page: That "Repost Page" is a dedicated Page layout used into the Modern Page, showing the user the news published in another Teamsite (cf. Communication Hub Site to understand the logic). The Hub Site is creating this without any user action, but anyone with the contribution access into a modern teamsite can create a "Repost Page" (named "News Link") to republish into his teamsite something published initially somewhere else (like the Retweet). It could be a link into the SharePoint, but also pointing anything else (Bing News for example). When you are clicking that link, the system will ask you to put first the destination Link and after complete the Image, the title and the description When that creation is done, the "Repost Page" will be visible into the Modern News webpart like any other News page but also into the Global Tenant Root page: https://[YourTenant].sharepoint.com/_layouts/15/sharepoint.aspx> So you can dedicate someone to republish the Publishing News into a Modern Page Library using the Repost Page layout, but that will not be so nice for him, and the PowerShell script cold be a good idea to do that. PowerShell script to create the Repost Page: Based on the previous message published: How to create Repost Page (Modern Page Library) with PowerShell I created this script fully adapted to my case and has 3 functions: Get the last published news on the old portal based on the search engine and export it to CSV Load the CSV file to check if the repost page is yet existing (if not yet, create it) Change the metadata of the Modern Reports News to set the correct creator and author [string]$SitePagesURL ="https://YourTenant.sharepoint.com" [string]$PageLibPublicName = "Site Pages" [DateTime]$MyCSVPublishingDate = Get-Date [DateTime]$PortalPublishingDate = Get-Date [string]$MyCSVPublisher = "" [string]$MyCSVTitle = "" [string]$MyCSVNewsURL = "" [string]$MyCSVNewsPictureURL = "" [string]$MyCSVNewsDescription = "" [string]$CSVFileName = "ExportGlobalNewsItems.csv" [string]$NewsPageFileName = "" [string]$queryText = "ContentTypeId:0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D00DAB155038B062847A409F1E450E9E5E3* Path:https://yourTenant.sharepoint.com/yourintranet " [string]$srcrpattern = '(?i)src="(.*?)"' [string]$outputline = "" [int]$TempUserID = 0 # --------------------------------------------------------------------------------------------------------------- function Load-DLLandAssemblies { [string]$defaultDLLPath = "" # Load assemblies to PowerShell session $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll" [System.Reflection.Assembly]::LoadFile($defaultDLLPath) $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll" [System.Reflection.Assembly]::LoadFile($defaultDLLPath) $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll" [System.Reflection.Assembly]::LoadFile($defaultDLLPath) $defaultDLLPath = "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.SharePoint.Client.Search\v4.0_16.0.0.0__71e9bce111e9429c\Microsoft.SharePoint.Client.Search.dll" #$defaultDLLPath = "D:\TOOLS\SHAREPOINT\SP_ONLINE\sharepointclientcomponents\microsoft.sharepointonline.csom.16.1.8119.1200\lib\net40-full\Microsoft.SharePoint.Client.Search.dll" [System.Reflection.Assembly]::LoadFile($defaultDLLPath) } # --------------------------------------------------------------------------------------------------------------- Function Get-All-Intranet-News-Published-ExportCSV($MyctxTemp, $MyspoRootwebTemp) { # add references to SharePoint client assemblies and authenticate to Office 365 site - required for CSOM $keywordQuery = New-Object Microsoft.SharePoint.Client.Search.Query.KeywordQuery($MyctxTemp) $keywordQuery.QueryText = $queryText $keywordQuery.RowLimit = 50 $keywordQuery.TrimDuplicates=$false $keywordQuery.SelectProperties.Add("LastModifiedTime") $keywordQuery.SelectProperties.Add("Modified") $keywordQuery.SelectProperties.Add("ModifiedBy") $keywordQuery.SelectProperties.Add("IntranetPublisher") $keywordQuery.SelectProperties.Add("DescriptionResumeOWSTEXT") $keywordQuery.SelectProperties.Add("PublishingImage") $keywordQuery.SortList.Add("Modified","Desc") $searchExecutor = New-Object Microsoft.SharePoint.Client.Search.Query.SearchExecutor($MyctxTemp) $results = $searchExecutor.ExecuteQuery($keywordQuery) $MyctxTemp.ExecuteQuery() Write-Host $results.Value[0].ResultRows.Count Clear-Content $CSVFileName $outputline = '"NewsTitle";"PublisherEmail";"PublicationDate";"NewsURL";"NewsPictureURL";"NewsDescription";' Add-Content -Encoding UTF8 -Force $CSVFileName $outputline foreach($result in $results.Value[0].ResultRows) { $TempString = $result["Modified"].split(';')[0] $ImageURLsrc=([regex]$srcrpattern ).Matches($result["PublishingImage"]) | ForEach-Object { $_.Groups[1].Value } $ImageURLsrc=$SitePagesURL + $ImageURLsrc.split('?')[0] +"?RenditionID=9" $PortalPublishingDate=[datetime]::ParseExact([string]$TempString, 'M/d/yyyy h:mm:ss tt', [CultureInfo]::InvariantCulture) $PublisherDetails = $result["IntranetPublisher"].split('|') #Write-Host " ------>>> TempString:", $TempString #Write-Host " ------>>> PublisherDetails:", $PublisherDetails.Count, "- LastField:", $PublisherDetails[4].Trim() #Write-Host " ------>>> PublishingImage:", $result["PublishingImage"] #Write-Host " ------>>> Modified:", $result["Modified"] Write-Host " ---------------------------------------- " Write-Host " ------>>> NewsPath:", $result["Path"] Write-Host " ------>>> Title:", $result["Title"] Write-Host " ------>>> PublicationDate:", $PortalPublishingDate Write-Host " ------>>> IntranetPublisherEmail:", $PublisherDetails[4].Trim() Write-Host " ------>>> ImageURLsrc:", $ImageURLsrc Write-Host " ------>>> DescriptionResumeOWSTEXT:", $result["DescriptionResumeOWSTEXT"] Write-Host " ---------------------------------------- " #CSV file location, to store the result $outputline = '"'+ $result["Title"] +'";"'+ $PublisherDetails[4].Trim() +'";"'+ $PortalPublishingDate.ToString("dd.MM.yyyy hh:mm:ss") +'";"'+ $result["Path"] +'";"'+ $ImageURLsrc +'";"'+ $result["DescriptionResumeOWSTEXT"] +'";' Add-Content -Encoding UTF8 -Force $CSVFileName $outputline } } # --------------------------------------------------------------------------------------------------------------- Function Get-All-News-PageList-ComparedToCSV($MyctxTemp, $MyspoRootwebTemp) { $GlobalNewsPageCSV = Import-Csv -encoding UTF8 $CSVFileName -delimiter ";" $GlobalNewsPageCSV | Format-Table $Alllists = $MyspoRootwebTemp.Lists $MyPagelist = $Alllists.GetByTitle($PageLibPublicName) $MyPagelistItems = $MyPagelist.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery(9999)) $MyctxTemp.load($MyPagelistItems) $MyctxTemp.executeQuery() foreach($PageItem in $MyPagelistItems) { Write-Host "" Write-Host "" Write-Host " --------------------------------------------------------- " <# foreach($MyFieldval in $PageItem.FieldValues) { Write-Host " >>> FieldName:", $MyFieldval } #> $ModifiedByuser = $PageItem["Editor"] $CreatedByuser = $PageItem["Author"] Write-Host "ID:", $PageItem["ID"], "- Title:", $PageItem["Title"], "- Original Publication Date:", $PageItem["Modified"] Write-Host " ==>>> PromotedState:", $PageItem["PromotedState"], "- PageLayoutType:", $PageItem["PageLayoutType"] -ForegroundColor red Write-Host " ===> Modified by:", $ModifiedByuser.LookupValue, "[", $ModifiedByuser.LookupId, "] - Created by:", $CreatedByuser.LookupValue, "[", $CreatedByuser.LookupId, "]" Write-Host " >> _OriginalSourceUrl:", $PageItem["_OriginalSourceUrl"] -ForegroundColor magenta Write-Host " >> Description:", $PageItem["Description"] Write-Host " >> BannerImageUrl:", $PageItem["BannerImageUrl"].URL, "- URLDesc:", $PageItem["BannerImageUrl"].Description #[BannerImageUrl, Microsoft.SharePoint.Client.FieldUrlValue] Write-Host " >> ContentTypeId:", $PageItem["ContentTypeId"] # [ContentTypeId, 0x0101009D1CB255DA76424F860D91F20E6C4118002A50BFCFB7614729B56886FADA02339B00FB61AB42CC88E741A501DF164E1EDB74] $searchTerm = $PageItem["_OriginalSourceUrl"] $MyCSVPublishingDate = Get-Date $GlobalNewsPageCSV |Where-Object {$_.NewsURL -match $searchTerm} |foreach-object{ $MyCSVTitle=$_.NewsTitle; $MyCSVNewsURL=$_.NewsURL; $MyCSVPublisher=$_.PublisherEmail; $MyCSVPublishingDate=[datetime]::ParseExact($_.PublicationDate,'dd.MM.yyyy hh:mm:ss',$null) } if ($PageItem["_OriginalSourceUrl"] -eq $MyCSVNewsURL) { Write-Host " >>> CSV Title found:", $MyCSVTitle, "- CSV Publication Date:", $MyCSVPublishingDate, "- Publisher:", $MyCSVPublisher -ForegroundColor Yellow Write-Host " >> CSV NewsURL:", $MyCSVNewsURL -ForegroundColor magenta #Load Context for the target link page $PageItem["_OriginalSourceUrl"] $TempUri = new-object Uri($MyCSVNewsURL) [string]$TempserverRelativeURL = $TempUri.AbsolutePath [string]$MyTempSubWebURL = $MyCSVNewsURL.substring(0, $MyCSVNewsURL.IndexOf('Pages')) Write-Host " === >> MyTempSubWebURL:", $MyTempSubWebURL -ForegroundColor Yellow Write-Host " === >> TempserverRelativeURL:", $TempserverRelativeURL -ForegroundColor Yellow $MyDestinationPagectx = New-Object Microsoft.SharePoint.Client.ClientContext($MyTempSubWebURL) $MyDestinationPagectx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($cred.UserName,$cred.Password) $MyDestinationPagectx.RequestTimeout = 1000000 # milliseconds $MyDestinationPageweb = $MyDestinationPagectx.Web $MyDestinationPageSiteColl = $MyDestinationPagectx.Site $MyDestinationPagelist = $MyDestinationPageweb.Lists.GetByTitle("Pages") $MyDestinationPageFile = $MyDestinationPageweb.GetFileByServerRelativeUrl($TempserverRelativeURL); $MyDestinationPageFileitem = $MyDestinationPageFile.ListItemAllFields; $MyDestinationPagectx.Load($MyDestinationPageweb) $MyDestinationPagectx.Load($MyDestinationPageSiteColl) $MyDestinationPagectx.Load($MyDestinationPagelist) $MyDestinationPagectx.Load($MyDestinationPageFileitem) $MyDestinationPagectx.ExecuteQuery() Write-Host " === >> DestinationPage Site URL:", $MyDestinationPageSiteColl.Url, "- ID:", $MyDestinationPageSiteColl.ID -ForegroundColor white Write-Host " === >> DestinationPage Web URL:", $MyDestinationPageweb.Url, "- ID:", $MyDestinationPageweb.ID -ForegroundColor white Write-Host " === >> DestinationPage PageList Title:", $MyDestinationPagelist.Title, "- ID:", $MyDestinationPagelist.ID -ForegroundColor white Write-Host " === >> DestinationPage PageFile Title:", $MyDestinationPageFileitem["Title"].ToString(), "- ID:", $MyDestinationPageFileitem["UniqueId"].ToString() $MyEditoruserAccount = $MyspoRootwebTemp.EnsureUser("i:0#.f|membership|$($MyCSVPublisher)"); $MyctxTemp.load($MyEditoruserAccount) $MyctxTemp.executeQuery() Write-Host " ===> Modified Account Login:", $MyEditoruserAccount.LoginName -ForegroundColor Magenta $PageItem["Created_x0020_By"] = $MyEditoruserAccount.LoginName $PageItem["Modified_x0020_By"] = $MyEditoruserAccount.LoginName $PageItem["PromotedState"] = "2" $PageItem["PageLayoutType"] = "RepostPage" $PageItem["ClientSideApplicationId"] = "b6917cb1-93a0-4b97-a84d-7cf49975d4ec" $PageItem["_OriginalSourceSiteId"] = $MyDestinationPageSiteColl.ID $PageItem["_OriginalSourceWebId"] = $MyDestinationPageweb.ID $PageItem["_OriginalSourceListId"] = $MyDestinationPagelist.ID $PageItem["_OriginalSourceItemId"] = $MyDestinationPageFileitem["UniqueId"].ToString() $PageItem["Modified"] = $MyCSVPublishingDate; $PageItem["Created"] = $MyCSVPublishingDate; $PageItem["FirstPublishedDate"] = $MyCSVPublishingDate; $PageItem["Editor"] = $MyEditoruserAccount.Id; $PageItem["Author"] = $MyEditoruserAccount.Id $PageItem.Update() $MyctxTemp.ExecuteQuery() } else { Write-Host " >>> CSV Title not found:", $MyCSVTitle, "- Date:", $MyCSVPublishingDate, "- Publisher:", $MyCSVPublisher -ForegroundColor Red Write-Host " >> CSV NewsURL:", $MyCSVNewsURL -ForegroundColor Red } Write-Host " --------------------------------------------------------- " } } Function Get-All-CSVNews-ComparedToPageList($MyctxTemp, $MyspoRootwebTemp) { $GlobalNewsPageCSV = Import-Csv -encoding UTF8 $CSVFileName -delimiter ";" $GlobalNewsPageCSV | Format-Table foreach($CSVItem in $GlobalNewsPageCSV) { Write-Host " --------------------------------------------------------- " Write-Host " >> CSV NewsTitle:", $CSVItem.NewsTitle Write-Host " >> CSV NewsURL:", $CSVItem.NewsURL Write-Host " >> CSV PublisherEmail:", $CSVItem.PublisherEmail Write-Host " >> CSV PublicationDate:", $CSVItem.PublicationDate Write-Host " >> CSV NewsPictureURL:", $CSVItem.NewsPictureURL Write-Host " >> CSV NewsDescription:", $CSVItem.NewsDescription $MyCSVTitle = $CSVItem.NewsTitle $MyCSVNewsURL = $CSVItem.NewsURL $MyCSVPublisher = $CSVItem.PublisherEmail $MyCSVPublishingDate = [datetime]::ParseExact($CSVItem.PublicationDate,'dd.MM.yyyy hh:mm:ss',$null) $MyCSVNewsPictureURL = $CSVItem.NewsPictureURL $MyCSVNewsDescription = $CSVItem.NewsDescription #Load Context for the target link page $PageItem["_OriginalSourceUrl"] $TempUri = new-object Uri($MyCSVNewsURL) [string]$TempserverRelativeURL = $TempUri.AbsolutePath [string]$MyTempSubWebURL = $MyCSVNewsURL.substring(0, $MyCSVNewsURL.IndexOf('Pages')) Write-Host " === >> MyTempSubWebURL:", $MyTempSubWebURL -ForegroundColor Yellow Write-Host " === >> TempserverRelativeURL:", $TempserverRelativeURL -ForegroundColor Yellow $MyDestinationPagectx = New-Object Microsoft.SharePoint.Client.ClientContext($MyTempSubWebURL) $MyDestinationPagectx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($cred.UserName,$cred.Password) $MyDestinationPagectx.RequestTimeout = 1000000 # milliseconds $MyDestinationPageweb = $MyDestinationPagectx.Web $MyDestinationPageSiteColl = $MyDestinationPagectx.Site $MyDestinationPagelist = $MyDestinationPageweb.Lists.GetByTitle("Pages") $MyDestinationPageFile = $MyDestinationPageweb.GetFileByServerRelativeUrl($TempserverRelativeURL); $MyDestinationPageFileitem = $MyDestinationPageFile.ListItemAllFields; $MyDestinationPagectx.Load($MyDestinationPageweb) $MyDestinationPagectx.Load($MyDestinationPageSiteColl) $MyDestinationPagectx.Load($MyDestinationPagelist) $MyDestinationPagectx.Load($MyDestinationPageFileitem) $MyDestinationPagectx.ExecuteQuery() Write-Host " === >> DestinationPage Site URL:", $MyDestinationPageSiteColl.Url, "- ID:", $MyDestinationPageSiteColl.ID -ForegroundColor white Write-Host " === >> DestinationPage Web URL:", $MyDestinationPageweb.Url, "- ID:", $MyDestinationPageweb.ID -ForegroundColor white Write-Host " === >> DestinationPage PageList Title:", $MyDestinationPagelist.Title, "- ID:", $MyDestinationPagelist.ID -ForegroundColor white Write-Host " === >> DestinationPage PageFile Title:", $MyDestinationPageFileitem["Title"].ToString(), "- ID:", $MyDestinationPageFileitem["UniqueId"].ToString() $MyEditoruserAccount = $MyspoRootwebTemp.EnsureUser("i:0#.f|membership|$($MyCSVPublisher)"); $MyctxTemp.load($MyEditoruserAccount) $MyctxTemp.executeQuery() $MyPagelist = $MyspoRootwebTemp.Lists.GetByTitle($PageLibPublicName) $MyQuery = New-Object Microsoft.SharePoint.Client.CamlQuery; $MyQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='_OriginalSourceUrl' /><Value Type='Text'>$MyCSVNewsURL</Value></Eq></Where></Query></View>" $MyPagelistItems = $MyPagelist.GetItems($MyQuery); $MyctxTemp.Load($MyPagelistItems) $MyctxTemp.ExecuteQuery() if($MyPagelistItems.Count -lt 1) { [string]$NewsPageFileName = "/yourintranet/SitePages/"+ $MyCSVPublishingDate.ToString("yyyyMMdd") +'-'+ $CSVItem.NewsURL.Substring($CSVItem.NewsURL.LastIndexOf("/") + 1) Write-Host " >> $($MyPagelistItems.Count) PageList Item Found, Need to be created [ $NewsPageFileName ]" -ForegroundColor Red # TO CREATE !!! $NewPageitem = $MyPagelist.RootFolder.Files.AddTemplateFile($NewsPageFileName, [Microsoft.SharePoint.Client.TemplateFileType]::ClientSidePage).ListItemAllFields # Make this page a "modern" page $NewPageitem["ContentTypeId"] = "0x0101009D1CB255DA76424F860D91F20E6C4118002A50BFCFB7614729B56886FADA02339B00874A802FBA36B64BAB7A47514EAAB232"; $NewPageitem["PageLayoutType"] = "RepostPage" $NewPageitem["PromotedState"] = "2" $NewPageitem["Title"] = $CSVItem.NewsTitle $NewPageitem["ClientSideApplicationId"] = "b6917cb1-93a0-4b97-a84d-7cf49975d4ec" $NewPageitem["_OriginalSourceSiteId"] = $MyDestinationPageSiteColl.ID $NewPageitem["_OriginalSourceWebId"] = $MyDestinationPageweb.ID $NewPageitem["_OriginalSourceListId"] = $MyDestinationPagelist.ID $NewPageitem["_OriginalSourceItemId"] = $MyDestinationPageFileitem["UniqueId"].ToString() $NewPageitem["_OriginalSourceUrl"] = $MyCSVNewsURL $NewPageitem["Editor"] = $MyEditoruserAccount.Id $NewPageitem["Author"] = $MyEditoruserAccount.Id $NewPageitem["Description"] = $MyCSVNewsDescription $NewPageitem["BannerImageUrl"] = $MyCSVNewsPictureURL; $NewPageitem["Modified"] = $MyCSVPublishingDate; $NewPageitem["Created"] = $MyCSVPublishingDate; $NewPageitem["Created_x0020_By"] = $MyEditoruserAccount.LoginName $NewPageitem["Modified_x0020_By"] = $MyEditoruserAccount.LoginName $NewPageitem["FirstPublishedDate"] = $MyCSVPublishingDate; $NewPageitem.Update(); $MyctxTemp.Load($NewPageitem); $MyctxTemp.ExecuteQuery(); } elseif($MyPagelistItems.Count -eq 1) { Write-Host " >> $($MyPagelistItems.Count) Page Item Found, Case OK !!!" -ForegroundColor Yellow # TO CHECK AND UPDATE VIA SCRIPT !!! #Loop through each item (only one if that is OK) $MyPagelistItems | ForEach-Object { #Get the Title field value Write-Host " >> PageList NewsTitle:", $_["Title"] -ForegroundColor Yellow Write-Host " >> PageList NewsUrl:", $_["_OriginalSourceUrl"] -ForegroundColor Yellow if($MyCSVNewsPictureURL -ne $_["BannerImageUrl"].URL) { $_["BannerImageUrl"].URL = $MyCSVNewsPictureURL $_["BannerImageUrl"].Description = $MyCSVNewsPictureURL } $_["PromotedState"] = "2" $_["Modified"] = $MyCSVPublishingDate; $_["Created"] = $MyCSVPublishingDate; $_["FirstPublishedDate"] = $MyCSVPublishingDate; $_["_OriginalSourceSiteId"] = $MyDestinationPageSiteColl.ID $_["_OriginalSourceWebId"] = $MyDestinationPageweb.ID $_["_OriginalSourceListId"] = $MyDestinationPagelist.ID $_["_OriginalSourceItemId"] = $MyDestinationPageFileitem["UniqueId"].ToString() $_["Editor"] = $MyEditoruserAccount.Id; $_["Author"] = $MyEditoruserAccount.Id $_["Created_x0020_By"] = $MyEditoruserAccount.LoginName $_["Modified_x0020_By"] = $MyEditoruserAccount.LoginName $_.Update() $MyctxTemp.ExecuteQuery() } } else { Write-Host " >> $($MyPagelistItems.Count) PageList Item Found, Need to be fixed !!!" -ForegroundColor Red # TO CHECK AND CONTROL MANUALLY !!! $MyPagelistItems | ForEach-Object { #Get the Title field value Write-Host " >> PageList NewsTitle:", $_["Title"] -ForegroundColor Yellow Write-Host " >> PageList NewsUrl:", $_["_OriginalSourceUrl"] -ForegroundColor Yellow } } } } # --------------------------------------------------------------------------------------------------------------- Load-DLLandAssemblies #get and save your O365 credentials [string]$username = "AdminAccount@Yourtenant.onmicrosoft.com" [string]$PwdTXTPath = "C:\SECUREDPWD\ExportedPWD-$($username).txt" $secureStringPwd = ConvertTo-SecureString -string (Get-Content $PwdTXTPath) $cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd #connect to the web site using the stored credentials Write-host " " Write-host " -------------------------------------------------------------------------------------------- " -ForegroundColor green Write-host " ---- CONNECT THE SITE --- " -ForegroundColor green Write-host " CONNECTED SITE:", $SitePagesURL -ForegroundColor Yellow $Myctx = New-Object Microsoft.SharePoint.Client.ClientContext($SitePagesURL +"/yourintranet") $Myctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($cred.UserName,$cred.Password) $Myctx.RequestTimeout = 1000000 # milliseconds $MyspoRootweb = $Myctx.Web $Myctx.Load($MyspoRootweb) $Myctx.ExecuteQuery() Write-Host " " Write-Host " ---------------------------------------------------------" Write-Host " >>>> # Server Version:" $Myctx.ServerVersion " # <<<<<<" -ForegroundColor Green Write-Host " ---------------------------------------------------------" Write-Host " " Write-host " -------------------------------------------------------- " Write-host " -->> RootSite:", $MyspoRootweb.URL -ForegroundColor green Write-host " " Get-All-Intranet-News-Published-ExportCSV $Myctx $MyspoRootweb Get-All-CSVNews-ComparedToPageList $Myctx $MyspoRootweb Get-All-News-PageList-ComparedToCSV $Myctx $MyspoRootweb You can easily modify it with your own requirements, but I use it now to enrich the last 500 published news into the modern library, and that was working perfectly. Fabrice Romelard French version: SharePoint: Comment Utiliser les Modern Pages dans un Site Intranet basé sur le Publishing site4.1KViews4likes0CommentsAnnouncement: SharePoint innovations further advance intelligence and collaboration in Office 365
Today at Microsoft Ignite, Microsoft announced the next wave of innovations. Here are some of the highlights: A significant update to the OneDrive browser experience, so that you can find, access, share and collaborate on allyour files in Office 365. OneDrive sync preview for SharePoint Online document libraries and folders shared with you. Team news to keep your team up to date and informed of what matters. People cards in SharePoint and OneDrive for Business that intelligently surface content and details from your colleagues’ profiles. New integration with Microsoft Flow, PowerApps and Yammer. Preview of the SharePoint mobile apps for Windows 10 Mobile and Android. Enhancements for developers including new sites and lists APIs in Microsoft Graph. New security controls including site classification and conditional access based on location and device. Feature Pack 1 for SharePoint Server 2016. Expanded FastTrack services and tools to support hybrid configurations and migration. Read more on Office Blogs.988Views4likes0CommentsNew SharePoint Online Management Shell - August 2017
I saw that a new version of the SharePoint Online Management Shell was released this week - version 16.0.6802.1200. https://www.microsoft.com/en-us/download/details.aspx?id=35588 VesaJuvonen are there any notes for changes in this release?Solved1.3KViews3likes2Comments