Office 365 guide series – Manage files and folders with PowerShell and CSOM


 Office365logo       SP2013logo

How to manage files and folders with PowerShell and CSOM

DocLib1

How can we manage these items…?

This is a pure guide to using PowerShell to manage and manipulate files and folders, libraries and all document management related tasks in a SharePoint Online or OneDrive for Business environment.

The sections in this guide are:

– Prerequisites
– Load assemblies
– Load a CSOM Context
– Web
– List/Library
– GetFileByServerRelativeUrl and GetForlderByServerRelativeUrl
– Create a file from a local copy
– Create a folder from a local copy
– Set properties on a file
– Set properties on a folder
– ResolveUser (Function)
– GetItemProperties (Function)

Prerequisites

Before beeing able to do much in SharePoint Online or OneDrive for Business, you have to start using CSOM, or Client Side Object Model, this allows us to do pretty much everything we could do before using regular PowerShell and the SharePoint CMD’lets from the SharePoint PowerShell add-on.
Install assemblies:
Download and install ther latest version of the SharePoint Server 2013 Client Components SDK, this can be downloaded from here: http://www.microsoft.com/en-us/download/details.aspx?id=35585
After the SDK and the CSOM assembly DLL’s are in place, make sure you load the assemblies before calling them.

Load assemblies

 Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
 Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

This will open up for usage of CSOM in PowerShell.

Load a context

$SPOUser = "administrator@blksthl.onmicrosoft.com"
# Uses a hardcoded password, use only during test/lab:
$SPOPassword = convertto-securestring "Password01" -asplaintext -force
# Better: $SPOPassword = Read-Host -Prompt "Please enter your password" -AsSecureString
$SPOODfBUrl = "https://blksthl.sharepoint.com/personal/jeffrey_lebowski_blksthl_com"
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SPOODfBUrl)
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($SPOUser,$SPOPassword)
$Context.RequestTimeout = 16384000
$Context.Credentials = $Credentials
$Context.ExecuteQuery()

Returns: $Context

Web

(Using $Context from the section on Context above)

$Web = $Context.Web
$Context.Load($Web)
$Context.ExecuteQuery()

Returns: $Web

List/Library

$SPODocLibName = "Documents"
$SPOList = $Web.Lists.GetByTitle($SPODocLibName)
$Context.Load($SPOList.RootFolder)
$Context.ExecuteQuery()

Returns: $SPOList

GetFileByServerRelativeUrl and GetForlderByServerRelativeUrl

In order to use the ‘Get…ByServerRelativeUrl’ methods you have to supply a relative path to the file or folder, this means a path starting from the FQDN.

Example 1
https://company.sharepoint.com/get/fileorfolder/by/relative/url
FQDN: https://company.sharepoint.com
ServerRelativeUrl: /get/fileorfolder/by/relative/url

Example 2
https://company-my.sharepoint.com/personal/firstname_lastname_company_com
FQDN: https://company-my.sharepoint.com
ServerRelativeUrl: /personal/firstname_lastname_company_com

Example file:

"/personal/jeffrey_lebowski_blksthl_com/documents/report1.xlsx"

Example folder:

 "/personal/jeffrey_lebowski_blksthl_com/documents/subfolder"

Create a file from a local copy

This can be accomplished in several ways, this is one:

1.
$LocalFile = Get-ChildItem -path "C:\Homedirs\jeff\report1.xlsx"
$FolderRelativeUrl = $SPOList.RootFolder.ServerRelativeUrl
$FileName = $LocalFile.Name
$FileUrl = $FolderRelativeUrl + "/" + $FileName
[Microsoft.SharePoint.Client.File]::SaveBinaryDirect($Web.Context, $fileUrl, $LocalFile.OpenRead(), $true)

Returns: New file created in SPO/ODfB

Create a folder from a local copy

$SPOFolder = $SPOList.RootFolder
$LocalFolder = Get-ChildItem -path "C:\Homedirs\jeff\" -Recurse -Include "folder1" 
$FolderName = $LocalFolder.Name
$NewFolder = $SPOFolder.Folders.Add($FolderName)
$Web.Context.Load($NewFolder)
$Web.Context.ExecuteQuery()

Returns: New folder created in SPO/ODfB

Set properties on a file

Input: $FileRelativeUrl, $SPOItemModifier, $SPOItemOwner, $ItemCreated, $ItemModified

$CurrentFile = $Context.web.GetFileByServerRelativeUrl($FileRelativeUrl)
$Context.Load($CurrentFile)
$Context.ExecuteQuery()
$ListItem = $CurrentFile.ListItemAllFields;
$ListItem["Editor"] = $SPOItemModifier; # Get object from ResolveUser
$Listitem["Author"] = $SPOItemOwner; # Get object from ResolveUser
$Listitem["Created"] = $ItemCreated;
$Listitem["Modified"] = $ItemModified;
$ListItem.Update()
$Context.Load($CurrentFile)
$Context.ExecuteQuery()

Returns: Folder stamped with new properties in SPO/ODfB

Set properties on a folder

Input: $FolderRelativeUrl, , $SPOItemModifier, $SPOItemOwner, $ItemCreated, $ItemModified

$CurrentFolder = $Context.web.GetFolderByServerRelativeUrl($FolderRelativeURL)
$Context.Load($CurrentFolder)
$Context.ExecuteQuery()
$SPOFolderItem = $CurrentFolder.ListItemAllFields;
$SPOItemOwner = ResolveUser $UserEmail # For ResolveUser see separate function described later in this post
$SPOFolderItem["Editor"] = $SPOItemModifier # Must be a userobject, see 'ResolveUser'
$SPOFolderItem["Author"] = $SPOItemOwner # Must be a userobject, see 'ResolveUser'
$SPOFolderItem["Created"] = $ItemCreated # In the format: "8/10/2013 7:04 PM", see 'GetItemProperties'
$SPOFolderItem["Modified"] = $ItemModified # In the format: "8/10/2013 7:04 PM", see 'GetItemProperties'
$SPOFolderItem.Update()
$Context.Load($CurrentFolder)
$Context.ExecuteQuery()

Returns: Folder stamped with new properties in SPO/ODfB

ResolveUser (Function)

Function ResolveUser ($InputUPN)
# Resolves a user to a userobject
{
    $OutputUserObject = $Web.Context.web.EnsureUser($InputUPN)
    $Web.Context.Load($OutputUserObject)
    $Web.Context.ExecuteQuery()
    Return $OutputUserObject
}

Returns: UserObject for $InputUPN (UserPrincipalName/Email)

GetItemProperties (Function)

Function GetItemProperties ($InFileObject)
# Gets basic properties to set on files and folders
{
    $Global:ItemCreated = $InFile.CreationTime
    $Global:ItemModified = $InFile.LastWriteTime
}

Returns: Global: Variables for ItemCreated and LastWriteTime of $InFileObject (File or Folder)

Thats all for now, I hope that you let me know if there is anything that seems to be wrong or does not work. The problem with describing all this in a complete way, is that it is easy to leave something out and it is also difficult to test every aspect while writing. Time is limited for all of us…
Anyway, my goal was to write a post that covered what I was myself missing…I hope that this is it. And again, please let me know if there are any mistakes in here.

References and Credits

None at this time…

Credits & many thanks to

LabCenter – you guys always publish my articles!

My family, my parents, Ia and the kids!

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Advertisement

Office 365 News – New document now supports Content types in SharePoint Online


 Office365logo       SP2013logo

‘new document’ now supports Content types in SharePoint Online

Thank you Microsoft, Content types just got user friendly and easy to use and promote!

ContentTypes1x

The new- new document dialog

Before yesterday, I knew that the ‘new document’ button in a document library became useless when you enabled Content types in a document library. This has for me and many of my customers been a huge drawback since the ‘new document’ button was still there, in plain view and for the regular user, what they were meant to use.

This old behavious was that when you pressed on ‘new document’ in a document library with multiple content types, you got the upload document dialog.

Upload dialog2

Old behaviour

What I was so glad to discover yesterday, during a live demo at a customer, that this has been fixed now in SPO! Instead of the upload dialog, I could now get this:

ContentTypes1

Fixed!

One down!
Next step, make content types available to Office Online…(They still seem to require the Office Applications installed on the client, nothing for E1 users or less in other words…)
I would also like the new folder option back with the content types 🙂

References and Credits

None at this time…

Credits & many thanks to

Cramo, this is where I did the demo when this change presented itself to me! A pleasure to work with you guys!

 

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 News – Unannounced Microsoft change to SharePoint Online access


 Office365logo       SP2013logo

Microsoft recently made a change to the way users can access SharePoint Online, this may affect many thousands of customers without them knowing…

Licensex

It has been disclosed to me that Microsoft has implemented a change on all Office 365 tenants to the way an unlicensed user can access SharePoint Online services…in a bad way…

Previously, the behaviour was that if you did not give a user a the SharePoint license in Office 365, the user could not access SharePoint.
This is the expected behaviour and this is how most companies restricted access to SharePoint Before they were ready to offer the service to their organizations.
This is no more, or at least not the current behaviour…Microsft has ‘temporarily’ made a change that allows ALL users, with a license or not to have access to all SharePoint Services.
The imidiate affect may be that your organization sleeps safely in the belief that SHarePoint may not be accessed, except by you in IT or by a limited number of individuals, meanwhile, the users go crazy and start using SharePoint in ways you never intended…

Well, this is something I don’t like, I would like this change to be limited to the ones who specifically asked for it, and if you needed it, you could request it, not the other way around.

Note 1: If you find that you do not want this behaviour, you want access only to your licensed users. Open a Service Request with Microsoft and ask them to change it back, they will help you then.

Note 2: The change does not affect OneDrive for Business, unprovisioned users do not get access to their ODfB without the SharePoint license.

The reason given by Microsoft representatives is this: Microsoft recognizes assigning licenses to users that are synced to the O365 services is cumbersome for larger tenants, to alleviate this pain point; a temporary change has been released to SharePoint Online that will allow users to access SharePoint Online even without license.’

 

References and Credits

None at this time…

Credits & many thanks to

Pihlen!

 

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 News – Newly Introduced security feature in SPO hides the Web Designer Galleries


 Office365logo       SP2013logo

Newly introduced security feature in SharePoint Online hides the Web Designer Galleries, Save site as template and a lot more too…

AdminSPO Admin setting (with a dead link)

During the end of 2014, beginning of 2015, a new security feature in SharePoint Online has been rolled out. The feature in itself is great, it has been introduced to (From the SharePoint admin interface):

Control whether users can run custom script on personal sites and self-service created sites.  Note: changes to this setting might take up to 24 hours to take effect.

What is good to know without Reading too much on this feature, is that these things for example will be missing:

Site feature Behavior Notes
Save Site as Template No longer available in Site Settings. You can still build sites from templates created before scripting was disabled.
Save document library as template No longer available in Library Settings. You can still build document libraries from templates created before scripting was disabled.
Solution Gallery No longer available in Site Settings. You can still use solutions created before scripting was disabled.
Theme Gallery No longer available in Site Settings. You can still use themes created before scripting was disabled.
Help Settings No longer available in Site Settings. You can still access help file collections available before scripting was disabled.
Sandbox solutions Solution Gallery will not appear in the Site Settings so you can’t add, manage, or upgrade sandbox solutions. You can still run sandbox solutions that were deployed before scripting was disabled.
SharePoint Designer Site Pages: No longer able to update web pages that are not HTML.Handling List: Create Form and Custom Action will no longer work.Subsites: New Subsite and Delete Site redirect to the Site Settings page in the browser. Data Sources: Properties button is no longer available. You can still open data sources.

For a good detailed description of what the feature does, have a look here. It affects mostly Everything and since it is activated by default, a lot of settings and functionality is suddenly missing. The feature has two ‘levels’, for personal sites and for self service created sites. (for me, it affects all site Collections)

Turn scripting capabilities on and off (Microsoft support article)
https://support.office.com/en-us/article/Turn-scripting-capabilities-on-and-off-1f2c515f-5d7e-448a-9fd7-835da935584f?ui=en-US&amp

The feature in itself is great, but perhaps, since it removes so much of the default functionality, it should have been left off be default? Or, would cause some kind of popup to all affected users?

Well, it is here now anyway…lets consider the feature a great idea, it increases the built in security of SharePoint Online and OneDrive for Business!

The complete list of settings affected and webparts missing: Save Site as Template, Save document library as template, Solution Gallery, Web Designer Galleries, Theme Gallery, Help Settings, Sandbox solutions, the Blog Archives, Blog Notifications, Blog tools Blog Webparts, the Business Data Actions, Business Data Item, Business Data Item Builder, Business Data List, Business Data Related List, Excel Web Access, Indicator Details, Status List, Visio Web Access Business Data Webparts, the About This Community, Join, My Membership, Tools, What’s Happening Community Webarts, the Categories, Project Summary, Relevant Documents, RSS Viewer, Site Aggregator, Sites in Category, Term Property, Timeline, WSRP Viewer, XML Viewer Content Rollup Webparts, the Document Set Contents, Document Set Properties Document Sets Webparts, the HTML Form Webpart, the Content Editor, Script Editor, Silverlight Webpart Media and Content Webparts, the Refinement, Search Box, Search Navigation, Search Results Search Webparts, the Catalog-Item Reuse Search-Driven Content Webparts and the Contact Details, Note Board, Organization Browser, Site Feed, Tag Cloud, User Tasks Social Collaboration Webparts.

References and Credits

None at this time…

Credits & many thanks to

Everyone!   SP2013logo _________________________________________________________ Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 News – OneDrive for Business sync client for MAC released


 Office365logo       SP2013logo

OneDrive for Business sync client for MAC released! – January 28, 2015

Finally, after too long, Microsoft has released the first preview version of a sync client to the MAC plattform.
Until now, this was the last gap in the ODfB access portfolio, now we can finally say, no more. We are complete! (Or soon will be anyway, it’s a preview…)
All is now covered, Windows, Windows Phone, Android phone, Android tablet, Iphone, Ipad and now, MAC OSX.

Download the preview here, OneDrive for Business Mac sync client Preview – Download Center

Read more about this news here on the Official OneDrive blog (Also covers OneDrive for Business…)

Mac ODB

Read the official story on the Office 365 blog about this news here:
http://blogs.office.com/2015/01/28/onedrive-business-comes-mac-ios-devices/

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 guide series – 101 ways to share a document


 Office365logo       SP2013logo

101 ways to share a document.

Fellow SharePoint lovers! (And OneDrive for Business…)

SharedLove

Share the Love

More and more individuals and organizations are starting to realize the beauty of OneDrive for Business, the way it allows you to be always up to date and to be able to always access your information no matter where you are or on what device you are on.

This article will delve© into detail on how you can keep the information in one place, instead of spreading multiple copies and versions around like we have always done using email as the sharing method of choice (Not to mention USB sticks). As you all most likely know, every time you send an email with an attachment of one of your files, a new copy and possible a new version of that document is created, it happens out of your control as well and this is not something that we want, it has simply been the only way to share, externally for sure and internally it has been the easiest way for the lazy.

Now, what has changed? What’s new? What’s so special with OneDrive for Business so that we can share thru some kind of Microsoft magic and files never have to be sent in email? What’s up with that? Well, implementing OneDrive for Business as a part of Office 365 is one step, you can however still work like you always have…removing the old Home directory and the Shared folders is another. You can however still work like you always have, sending attachments using email, but, these steps will allow you and your coworkers to adopt a new way of doing things, a better more secure and controlled way to work.

ShareTrad1

Traditional sharing, send a copy of the original to each user, same as when printing a letter and posting it…

ShareNew1

Modern sharing, one original, no copies. Everyone reads or edits the same file.

As you all also probably know and think right now, there are other cloud services that can do this and yes, I agree, but if you have invested in Office 365 already, then you get OneDrive for Business with 1TB (!) storage for free (or it is included in the price but free sounds better, and compared to using a different service like dropbox or box, then it IS free). You have a single sign on between the different applications in Office 365 and if you have implemented ADFS, then you will even have single sign on from your PC. Yes, I know that storage will be unlimited soon…but honestly, 1TB IS unlimited…

But enough of that, now I will show you where you can share a document from your OneDrive for business.

First off, there is a setting that are configured globally in the SharePoint admin portal of Office 365 that we need to know about.

Share1

External Sharing, there are 3 levels to select from. Can be set on the tenant or per Site collection. This setting can only be configured by a Global Office 365 Administrator.
The third level means anonymous access…(No! You really shouldn’t)

Share2

(Note also that if you restrict sharing on the tenant, then you cannot allow it on the site collection level) When these are set, you can start sharing.

There are a lot of places to do this for the mobile OneDrive for Business user

Share3

– OneDrive for Business Online
– OneDrive for Business Offline (from the local cache)
– The Office Applications
– The OneDrive for Business mobile app (Windows Phone, IOS, Android)
– Office Mobile (Windows Phone, IOS, Android) only shares a link, does not grant access
– Outlook Online (formerly known as Outlook Web Access)

It is more or less the same experience everywhere, the web dialog for sharing a document looks like this, from here you can share with internal users as well as external users, and all you need is an email address.

OneDrive for Business Online

Share4

Click SHARE then select how to share, or select the document(s) and click on the Share ‘button’

Share5

The dialog then looks like this

Share6

As you can see, the checkbox for ‘Require sign-in’ is checked by default, unchecking that allows anonymous access to this document.
This checkbox is only available if anonymous sharing is enabled at the tenant and at the site collection level.

The names can be internal users by name or email address, it can be external users by email or it can be everyone.

Share7

The permission level can also be set here, they speak for themselves. (Note that sharing with edit allows the recipient to in turn share with or without edit)

Share8

You can type in a message, this will be the text in the email that is sent to the recipient

Share9

Under SHOW OPTIONS you have the option to not send an email at all.

Share10

The recipient receives an email with this content

Share11

Clicking the link takes the user straight to the shared file, in its location.

Under Shared with, you can see who currently has access to this document.

Share12

When a document is shared, you can also see that the little user icon is replaced to show that someone else besides you now also has access to this document or this file.

Share13

Unshare the file again by clicking on that icon and in the Shared with dialog, select Stop sharing and save Changes.

Share135

After a quick refresh, you will see that the little icon is back to the Padlock.

Share14

This is how you share things in the OneDrive for Business Online, it is very similar in SharePoint Online (A few exceptions like unsharing differs).

The rest you will know when you see them:

The OneDrive for Business Offline (from the local cache)

Share15

The Office Applications

Share16

The OneDrive for Business mobile app (Windows Phone, IOS, Android)

Share17

Office Mobile, Word, Excel, PowerPoint (Windows Phone, IOS, Android) only shares a link, does not grant access

Share18

Outlook Online (formerly known as Outlook Web Access)

Select INSERT

Share19

Select Share with OneDrive (They really should stop confusing the business version with the consumer version…)

Share20

Apply the proper permission level, read or read/write

Share21

Share22

Note that the file is not sent as an attachment unless you specifically choose to do so. It only looks like an attachment, the file never leaves your personal OneDrive for Business.

And, to sum it all up, a message from inside Outlook Online:

Share23

SharedLove

 

References and Credits

None at this time…

Credits & many thanks to

LabCenter – you guys always publish my articles!

Mattias Gutke at Xperta

My family.

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 guide series – Prevent unwanted use of SharePoint Designer


 Office365logo       SP2013logo

SPD_Warning

SharePoint Designer, bad in the wrong hands

Prevent unwanted use of SharePoint Designer (SPD)

Hi SharePoint Online administrators!

You have all Heard the nickname SharePoint Destroyer right? I’m not a SharePoint Designer hater at all, quite the opposite actually. Some things can simply just be done from SPD and no Place else. Like for example saving a SharePoint online Site Collection from a failed branding attempt…or a miscoded masterpage…
No, SPD is a really good tool for the ones who know how to use it and with the proper skills and the proper permissions it can be a real help in many scenarios, onprem or in the cloud.

However, what I want to Point out here in this post, is that not everyone has the skills needed, and way to many users have too high permissions for their own good.
A powerfull tool like SPD in the wrong hands can be dangerous…
The only example we need: OneDrive for Business…until Microsoft makes a change and restricts every users completely unmotivated administrative privilieges to the OneDrive for Business/Mysite, we want to stop our users any way we can.

So, this is what I have found that can assist in this task in a Office 365 scenario:

1. Remove SPD as a download from Office 365 (Makes it harder)

2. Prevent the use of SPD (Not easy to accomplish in OneDrive for Business)

3. Educate your users. (Often not realistic at all)

1. Remove SPD as a download from Office 365

OK, if you did not know this, Office 365 has a link for every user, where they can freely or included in the license, download software. It includes the Office 365 Proplus and Lync+Outlook for Mac and more, one of the applications offered to the users is SharePoint Designer.
The link to download SharePoint Designer can be removed by a global Administrator though…(thank you Microsoft)
This is what you do:

Click the ‘startbutton’ in the Applauncher of your Office 365 tenant, then click on Admin

O365 Admin0

Expand Service Settings and select User Software

O365 Admin1x

Deselect the SharePoint Designer checkbox and hit Save.

O365 Admin2x

Done. This configuration will stop users from easily finding SharePoint Designer inside of Office 365

Note: Remember however, they can still install it from other sources.

If you did not know this, the software is installed by the users from here:

A

Software1x

B

Software2x

C

Software3x

This setting will be removed/Hidden from the user if you follow the steps above.

2. Prevent the use of SPD

Before ywe begin, this is NOT easily done in OneDrive for Business. Since every OneDrive for Business is its own Site Collection (or part of the mysite) it has to be configured on every single OneDrive for Business. And even if this is accomplished, it can be ‘unconfigured’ by the user since he/she has administrative privileges.

Stop the use of SharePoint Designer completely in a single Site Collection this way:

In the Site Settings menu, select the Site Collections Site Settings

Site Settings 1x

Select SharePoint Designer Settings

Site Settings 2x

Deselect Enable SharePoint Designer to stop its use completely. Or, if you rather let the users do some things but not all, select the minor options as you choose.

Site Settings 3x

Hit OK and you are safe!

3. Educate your users

This is actually not a bad idea, depending on the type of users and the kind of business you are and the size and so on, this can be the very best way, but it can also be the hardest, the most expensive and the least secure way.
My recommendation, do keep this in mind. It can be a good adea to put some trust in your users and give them some responsibility, sometimes…
How to do this step, that is not my area of expertese, but there are others who know this. If you are a small organization, use email! Or Office 365 Video?

With that, we are done for this time.

References and Credits

Organize your Office 365 with the new app launcher
http://blogs.office.com/2014/10/16/organize-office-365-new-app-launcher-2/

Introducing Office 365 Video
http://blogs.office.com/2014/11/18/introducing-office-365-video/

 

Credits & many thanks to

Always, Mattias Gutke, now at Xperta

My excellent colleges/coworkers at Xperta! All of you! My team, Johanna, Oscar, Micke and again, Mattias!

 

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 guide series – Verify Provisioned OneDrives using PowerShell


 Office365logo       SP2013logo

Hi SharePoint Online administrators!

This time I will show you how to:

Verify if a provisioned OneDrive for Business site was provisioned.

AminneBrukx

 Is this really right…? What did they…(Åminne bruk, Värnamo, Sweden)

 

If you followed my previous post, Office 365 guide series – Provision OneDrive for Business using PowerShell then you will mst likely have a bunch of sites that you Think you have provisioned and are not really sure if it worked?
There are obviously ways to verify manuelly but if the list of users was long, then that is not the funniest work out there…

I suggest you use this script instead…:-)

If you have a single emaildomains in your oranization use the first one, if you have multiple emaildomains, use the second.
All you have to do is copy or retype the script to a Prompt/ps1 or ISE session, then run the script. You have the option to save some time by entering your account name in the script(see start)

 

1. Script 1 Use this script if your organization only uses one domainname as email domain. For example, if you use only ‘contoso.com’ then you should use this script.
2. Script 2 Use this script if your organization only uses multiple domainnames as email domains. For example, if you use ‘contoso.com’, ‘microsoft.com’, northwindtraders.com’ as UPN names within your O365 tenant, then use this script. You will here be asked for the domain used in the O365 tenant address.
3. Example 1 Example of a usecase with multiple emaildomains and script 2.
4. Example 2 Example of a usecase with a single emaildomain and script 1.

Note: If you copy paste the code from here into a PowerShell promt or ISE, please verify that all quotes and doublequotes are copied correctly, character coding may cause problems. 

 

Single email domain in your oranization:

***** SCRIPT 1 STARTS HERE *****

#
# By Thomas Balkeståhl - http://blog.blksthl.com
#
$o365cred = Get-Credential -Username "thomas.balkestahl@cramo.onmicrosoft.com" -Message "Supply a Office365 Admin"
$Userlist = read-host "submit your list of users that have been provisioned"
$Userlist = $Userlist -replace " ", ""
$Emails = $userlist -split ","
#Splitting list into Array
Foreach($Email in $Emails)
{
    # Constructing URL from the UPN/Email address
    $struser = $Email
    $pos= $strUser.IndexOf("@")
    $len = $struser.Length -1
    $strUser = $strUser.SubString(0, $pos)
    $strUser = $strUser -replace "\.", "_"
    $orgpos = $pos + 1
    $orglen = $len - $pos
    $strOrg = $Email.SubString($orgpos, $orglen)
    $strOrgNamePos = $strOrg.IndexOf(".")
    $strOrgName = $strOrg.SubString(0, $strOrgNamePos)
    $strOrgSuffixPos = $strOrgNamePos +1
    $strOrgNameLen = $strOrg.Length - $strOrgSuffixPos
    $strOrgSuffix = $strOrg.SubString($strOrgSuffixPos, $strOrgNameLen)
    $strOrg = $strOrg -replace "\.", "_"
    $PersonalOrgURL = "https://" + $strOrgName + "-my.sharepoint.com/personal/"
    $SiteUrl= $PersonalOrgURL + $strUser
    $SiteUrl= $SiteUrl+ "_" + $strOrg
    write-host "Verifying user:" $Email
$HTTP_Request = [System.Net.WebRequest]::Create($SiteUrl)
$HTTP_Request.UseDefaultCredentials = $true
$HTTP_Request.Credentials = $o365cred
try {
    $HTTP_Response = $HTTP_Request.GetResponse()
}
catch [System.Net.WebException] {
    $HTTP_Response = $_.Exception.Response
}
$HTTP_Status = $HTTP_Response.StatusCode
If ($HTTP_Status -eq 200 -or $HTTP_Status -eq 403 )   { 
    Write-Host -ForegroundColor Green "Site for user $Email exists!" 
}
Else {
    Write-Host -ForegroundColor Yellow "The OneDrive site for user $Email does not respond, try again later or provision it again"
}
$HTTP_Request = $null
$HTTP_Response = $null
$HTTP_Status = $Null
}

***** SCRIPT 1 ENDS HERE *****

If you have multiple email domain in your oranization, use this second script:
***** SCRIPT 2 STARTS HERE *****

#
# By Thomas Balkeståhl - http://blog.blksthl.com
#
$O365Admin = read-host "Supply your Office 365 Admin username(UPN)"
# Add you admin account below, uncomment and comment out the line above to save time...
# $O365Admin = "admin.user@domain.com"
$o365cred = Get-Credential -Username $O365Admin -Message "Supply a Office365 Admin"
$strO365OrgName = read-host "submit your O365 orgname (Only organization, like 'contoso')"
$Userlist = read-host "submit your list of users that have been provisioned"
$Userlist = $Userlist -replace " ", ""
$Emails = $userlist -split ","
#SPlitting list into Array
Foreach($Email in $Emails)
{
    # Constructing URL from the UPN/Email address
    $struser = $Email
    $pos= $strUser.IndexOf("@")
    $len = $struser.Length -1
    $strUser = $strUser.SubString(0, $pos)
    $strUser = $strUser -replace "\.", "_"
    $orgpos = $pos + 1
    $orglen = $len - $pos
    $strOrg = $Email.SubString($orgpos, $orglen)
    $strOrgNamePos = $strOrg.IndexOf(".")
    $strOrgName = $strOrg.SubString(0, $strOrgNamePos)
    $strOrgSuffixPos = $strOrgNamePos +1
    $strOrgNameLen = $strOrg.Length - $strOrgSuffixPos
    $strOrgSuffix = $strOrg.SubString($strOrgSuffixPos, $strOrgNameLen)
    $strOrg = $strOrg -replace "\.", "_"
    $PersonalOrgURL = "https://" + $strO365OrgName + "-my.sharepoint.com/personal/"
    $SiteUrl= $PersonalOrgURL + $strUser
    $SiteUrl= $SiteUrl+ "_" + $strOrg
    write-host "Verifying user:" $Email
$HTTP_Request = [System.Net.WebRequest]::Create($SiteUrl)
$HTTP_Request.UseDefaultCredentials = $true
$HTTP_Request.Credentials = $o365cred
try {
    $HTTP_Response = $HTTP_Request.GetResponse()
}
catch [System.Net.WebException] {
    $HTTP_Response = $_.Exception.Response
}
$HTTP_Status = $HTTP_Response.StatusCode
If ($HTTP_Status -eq 200 -or $HTTP_Status -eq 403 )   { 
    Write-Host -ForegroundColor Green "Site for user $Email exists!"
}
Else {
    Write-Host -ForegroundColor Yellow "The OneDrive site for user $Email does not respond, try again later or provision it again"
}
$HTTP_Request = $null
$HTTP_Response = $null
$HTTP_Status = $Null
}

***** SCRIPT 2 ENDS HERE *****

Example 1

Multiple emaildomains
O365 Orgname: contoso
Users: test.user1@contoso.com, test.user2@northwind.com, test.user3@contoso.com, test.user4@contoso.com, test.user5@contoso.com

PS1

Like you can see, the list contains users with different emaildomains, contoso and northwind. THe submitted O365 orgname is however used to verify the OneDrive site, contoso.
In this example, the user test.user@contoso.com does not seem to have the OneDrive site provisioned.

Example 2

Single emaildomain
Users: test.user1@contoso.com, test.user2@contoso.com, test.user3@contoso.com, test.user4@contoso.com, test.user5@contoso.com

PS2

Like you can see, the list contains users with only contoso as emaildomain.
In this example, the user test.user2@contoso.com does not seem to have the OneDrive site provisioned. Try to provision again/verify manuelly.

References and Credits


Office 365 guide series – Provision OneDrive for Business using PowerShell
https://blog.blksthl.com/2014/08/07/office-365-guide-series-provision-onedrive-for-business-using-powershell/

 

Credits & many thanks to

Jörgen Andersson, Xperta

Always, Mattias Gutke at CAG

 

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn

Office 365 guide series – Provision OneDrive for Business using PowerShell


 Office365logo       SP2013logo

Hi SharePoint Online administrators!

This time I will show you how to:

Provision OneDrive for Business using only PowerShell.

Lisebergx

Get the people up there…into the Clouds…(Liseberg, Gothenburg, Sweden)

Time to roll out OneDrive for Business in the Enterprise? Or maybe you just want to implement OneDrive for Business in a controlled way, and you may not be a hardcore developer either.

If you want to do any kind of preparation before letting the users into their OneDrives, then you will need to have them created/provisioned first, after that you can go ahead and give yourself permission (separate blogpost) and migrate a users files (separate blogpost), preconfigure, brand, and so on.
I have in this guide tried to offer a way to provision the OneDrive for Business to your users in a way that do not require you to know C#, Visual Studio or any development at all, how does that sound? All you need to do is follow this guide to the letter, and you will be sucessfull.

The only way I have found so far to provision a users OneDrive for Business as a administrator is to use code developed by the Office AMS Community Project. This includes among other things, a great Visual Studio sample Project for provisioning users OneDrive for business, and this is really spot on. But…it is not that easy to get going, for a non-developer it may prove to be impossible.

I have used code developed in the samples but I will only use PowerShell to execute it. This is what will make it easy for others (such as you?) to use.
The Office AMS Project also includes the SharePoint client assemblies needed to do anything with SPO using CSOM, Client Side Object Model(Code executed on the client).

In order to get started provisioning your users OneDrive for Business sites(or we can just as well call them MySites, since this is wat they really are…), you just follow these steps:

Quickguide

1. Download Download and unpack the Office App Model Samples from Codeplex, last tested version is currently 2.0 found here: DOWNLOAD Office AMS.
2. Get assemblies Locate the Microsoft.sharepoint.client assembles in the unpacked Office App Model Samples folders, located in <unpack location>\Office App Model Samples v2.0\Assemblies\16\ Copy the files Microsoft.SharePoint.Client.dll, Microsoft.SharePoint.Client.UserProfiles.dll and Microsoft.SharePoint.Client.Runtime.dll and put them in a folder of your choice, I used C:\Temp\ in my sample. (You can also leave the files as is, but then you have to alter the PowerShell code to reference the path in the Office AMS folders)
3. Run the script In a PowerShell prompt/ISE running as admin, run the PowerShell script available below andHERE (Download as Word file), this will load the code needed to access SPO and start provisioning. (Verify and update if needed the $MyAssemblies line at the very bottom)
4. Execute Execute the code in your PowerShell prompt/ISE running as admin (It has to be the same prompt/ISE used to execute the script), use this syntax: Syntax: [OneDriveforBusiness.Provision]::Execute(<SharePointAdminURL>,<GlobalTenantAdminAccount>,<AdminAccountPassword>,<ListofUsersEmailSeparatedbyCommas>)
5. Done – Verify… Done! Verify that the sites have been provisioned by entering the address in your browser of choice.
References/Credits Reference links and credits

 

The detailed Guide:

1. Download

 

New!
Download the latest version of SharePoint Server 2013 Client Components SDK x86 or x64. This SDK contains the dll’s needed.
During the install, the dll’s will be added to the following path:
C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\

Download the latest version (Office App Model Samples 2.0 – July 2014 – Update 1) of the Office App Model Samples, the Project has been renamed to the more formal Office365 Developer Patterns & Practices but it is still the same.
The last tested version is currently 2.0 found here: DOWNLOAD Office AMS

 

Back to Menu

2. Get the assemblies

Unpack the files to a location of choice. (The files will ironically enough not synch very well if stored in a OneDrive for Business synchronized folder – long path among other issues).
Locate the ‘assemblies\16’ folder, in this folder you will find the 3 files we need, Microsoft.SharePoint.Client.dll, Microsoft.SharePoint.Client.UserProfiles.dll and Microsoft.SharePoint.Client.Runtime.dll. Either you put these Three files in a better location, or you make a note of the path to the folder.

Back to Menu

3. Run the script

Start a PowerShell prompt/ISE running as administrator. This is where all the magic will happen. Copy the powershell script below, or download the scriptfile HERE (Word file), then add the script to the Prompt/ISE.
Before executing the script, you will need to alter one thing, the path to the assembly files. Update the line where we give a value to the $MyAssemblies to reflect where you have your SharePoint.client dll files. This is crucial since the code needs to be able to access these asseblies during execution.

$MyAssemblies = (‘C:\Temp\Microsoft.SharePoint.Client.dll’,’C:\Temp\Microsoft.SharePoint.Client.Runtime.dll’,’C:\Temp\Microsoft.SharePoint.Client.UserProfiles.dll’,’System’,’System.Security’)

Unless you have stored your SharePoint.client.dll’s in C:\Temp folder, you will have to update the Three paths to reflect where the files are stored. Example:

$MyAssemblies = (‘C:\Users\Thomas\Documents\Office App Model Samples v2.0\Assemblies\16\Microsoft.SharePoint.Client.dll’,’C:\Users\Thomas\Documents\Office App Model Samples v2.0\Assemblies\16\Microsoft.SharePoint.Client.Runtime.dll’,’C:\Users\Thomas\Documents\Office App Model Samples v2.0\Assemblies\16\Microsoft.SharePoint.Client.UserProfiles.dll’,’System’,’System.Security’)

Once this is done, you can go ahead and execute the script.

HERE (Download as Word file)

# By Thomas Balkeståhl - blog.blksthl.com August 6 2014
#
# 1. Run script to load the C# code into the Assembly
# 2. Execute using the following syntax:
#
# Syntax:  [OneDriveforBusiness.Provision]::Execute(<SharePointAdminURL>,<GlobalTenantAdminAccount>,<AdminAccountPassword>,<ListofUsersEmailSeparatedbyCommas>)
# Example: PS C:\> [OneDriveforBusiness.Provision]::Execute("https://donkeymind-admin.sharepoint.com","globaladmin@donkeymind.com","MyVerySecretPassWord1!","user1@donkeymind.com,user2@donkeymind.com,user3@donkeymind.com")
# Input:            
# adminurl = The Tenanat Admin URL for your SharePoint Online Subscription, example: "https://donkeymind-admin.sharepoint.com".
# adminuser = The Credentials of the user who has tenant admin permission, example: "admin@donkeymind.com".
# password = The password in cleartext to your tenant admin account(I know, not ideal...but it was a quick and dirty to make it work).
# users = The email IDs for users who's personal site you want to create in the form of a comma-separated string, example: "user1@donkeymind.com,user2@donkeymind.com,user3@donkeymind.com". Do not enter more than 200 users at a time.
$MyCSharpSource = @" 
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.UserProfiles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;
namespace OneDriveforBusiness
{
    public class ProvisionOneDrive
    {
        public static void Execute(string adminurl, string adminuser, string password, string users)
        {
        
            string siteUrl = adminurl;
            string userName = adminuser;
        
            SecureString pwd = GetPassword(password);
            string[] emailIds = GetEmailId(users);
            /* End Program if no Credentials */
            if (string.IsNullOrEmpty(userName) || (pwd == null) || emailIds == null || string.IsNullOrEmpty(siteUrl))
                return;
            SharePointOnlineCredentials _creds = new SharePointOnlineCredentials(userName, pwd);
            CreatePersonalSiteUsingCSOM(_creds, siteUrl, emailIds);
            Console.Read();
        }
        public static SecureString StringToSecure(string nonSecureString)
        {
            SecureString _secureString = new SecureString();
            foreach (char _c in nonSecureString)
                _secureString.AppendChar(_c);
            return _secureString;
        }
        // tenantAdminUrl = The Tenanat Admin URL for your SharePoint Online Subscription
        // spoCredentials = The Credentials of the user who has tenant admin permission.
        // emailIDs = The email IDs for users whos personal site you want to create.
        public static void CreatePersonalSiteUsingCSOM(SharePointOnlineCredentials spoCredentials, string tenantAdminUrl, string[] emailIDs)
        {
            using (ClientContext _context = new ClientContext(tenantAdminUrl))
            {
                try
                {       
                    _context.AuthenticationMode = ClientAuthenticationMode.Default;
                    _context.Credentials = spoCredentials;
                    ProfileLoader _profileLoader = ProfileLoader.GetProfileLoader(_context);
                    _profileLoader.CreatePersonalSiteEnqueueBulk(emailIDs);
                    _profileLoader.Context.ExecuteQuery();
                    Console.Write("Provisioning of the users supplied has been initiated, please allow for the provisioning to finish, this can take up to 5 minutes.");
                }
                catch (Exception _ex)
                {
                    Console.WriteLine(string.Format("Provisioning failed, find the problem and try again. The error message is {0}", _ex.Message));
                }
            }
        }
        
        public static SecureString GetPassword(string password)
        {
            SecureString sStrPwd = new SecureString();
            foreach (char ch in password) sStrPwd.AppendChar(ch);
            return sStrPwd;
        }
        public static string[] GetEmailId(string users)
        {
            string[] emailID;
            try
            {
                string Output = "Provisioning the supplied list of users: " + users;
                Console.WriteLine(Output);
                string emailInput = users;
                if (!string.IsNullOrEmpty(emailInput))
                {
                    emailID = emailInput.Split(new char[] { ',' });
                    return emailID;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return null;
        }
    }
}
"@
$ass1 = [System.Reflection.Assembly]::LoadFile("c:\temp\Microsoft.SharePoint.Client.dll") 
$ass2 = [System.Reflection.Assembly]::LoadFile("c:\temp\Microsoft.SharePoint.Client.Runtime.dll") 
$ass3 = [System.Reflection.Assembly]::LoadFile("C:\temp\Microsoft.SharePoint.Client.UserProfiles.dll")
$MyAssemblies = @( $ass1.FullName, $ass2.FullName,$ass3.Fullname,"System","System.Core","System.Security")
Add-Type -ReferencedAssemblies $MyAssemblies -TypeDefinition $MyCSharpSource -Language CSharp -PassThru

HERE (Download as Word file)

Back to Menu

4 Executing the provisioning code

ISE2

We have now loaded the code into memory (a .NET Framework class in your Windows PowerShell session), where it will be available just like if we had created a C# DLL and loaded it into the GAC. Remember though, the code is now static and connot be altered. If you need to make any Changes, have a look in the references section where I will show how to be able to alter the code after it has been loaded once.

Now, we have to call on the code laoded into memory, this is done from the same prompt/ISE used to load the code, the code only exists in that prompt session so it will not be available in any other prompt.

Use the following syntax to execute:

Syntax: [OneDriveforBusiness.ProvisionOneDrive]::Execute(<SharePointAdminURL>,<GlobalTenantAdminAccount>,<AdminAccountPassword>,<ListofUsersEmailSeparatedbyCommas>)

Example: PS C:\> [OneDriveforBusiness.ProvisionOneDrive]::Execute(“https://donkeymind-admin.sharepoint.com&#8221;,”globaladmin@donkeymind.com”,”MyVerySecretPassWord1!”,”user1@donkeymind.com,user2@donkeymind.com,user3@donkeymind.com”) 

What you need to supply when running the code, is your SharePoint online admin address, a tenent admin account and password, plus a list of emailadresses to the users that will be provisioned with a OneDrive for Business.

Start by typing in this:

[OneDriveforBusiness.ProvisionOneDrive]::Execute

ISE4

What this does is call the code we just loaded from PowerShell, The Namespace is OneDriveforBusiness, the Class is ProvisionOneDrive and finally, the void or function is Execute.

<SharePointAdminURL>: The Admin address is available if you go the the Admin/SharePoint administration web. This will be visible in the address field of your browser:

Admin1x

Admin0x

Note the address: https://donkeymind-admin.sharepoint.com.

<GlobalTenantAdminAccount>: An account that is a global Office 365 Tenant Administrator.
The account must have this setting in Office 365 Admin Center/Users & Groups – User object:

Parameters1x

<AdminAccountPassword>: The password of the <GlobalTenantAdminAccount>. This will be entered in cleartext, not the ideal security solution but this is the only way I could solve it.
(Suggestions on how to prompt for the password in a secure way is welcome!)

<ListofUsersEmailSeparatedbyCommas>: This is the users that will have provisioned with OneDrive for Business. A list of UPN’s (User Principal Name) separated by commas. The UPN must be the one registered in Office 365. The UPN is in the form of a emailadress, for example: user@domain.com. Enter the string using double quotes on both sides.

This is what the string should look like: “user1@donkeymind.com, user2@donkeymind.com, user3@donkeymind.com, user4@donkeymind.com, user5@donkeymind.com”

When you have all the values in order, type in the command with your parameters and execute the provisioning:

PS C:\PSScripts> [OneDriveforBusiness.ProvisionOneDrive]::Execute(“https://donkeymind-admin.sharepoint.com&#8221;,”thomas@donkeymind.onmicrosoft.com”,”**********”,”testaccount@donkeymind.onmicrosoft.com”)

When executed ok, you will see this:

ISE9

The limit for submitting users to be provisioned have been set by Microsoft to 200 at the time. This code do allow more but it will cause issues. Better to do them 200 at the time, wait unitl done and then do 200 more, alternatively, alter the code to include a check so that every user have been provisioned ok Before moving onto the next.

Now, you can execute the commend again and again. You can also use the code obviously for other tenants. Simple provide the commend with a different account, a different admin URL and you are good to go. Good luck!

Back to Menu

5. Done! Verify….

For a tool to verify your list of users directly, check out this guide: Office 365 guide series – Verify Provisioned OneDrives using PowerShell

Verify that the sites have been provisioned by browsing to the direct URL using your admin account. The URL will look like this:

User: thomas.balkestahl@donkeymind.onmicrosoft.com
URL: https://donkeymind-my.sharepoint.com/personal/thomas_balkestahl_donkeymind_onmicrosoft_com/

User: han.solo@alliance.org
URL: https://donkeymind-my.sharepoint.com/personal/han_solo_alliance_com/

Since you are using your admin account, you have access to the private part of the OneDrive/MySite.

Note: All the steps in this guide have been verified on a Windows 8.1 Update 1 machine, using PowerShell ISE and the Office AMS July 2014 Update 1. All tests have been done during August of 2014, the functionality of Office 365 may change over time and may thus cause this guide to fail. If this happens I will try to be alert and update the guide accordingly. 

Possible errors

1. You need to alter the script, then run the script again?

You have two choices if this happens, you have loaded the code once and you need to edit it and run again. If you do this you may get the error message saying that the ‘Type has already been added’ or similar. If you get this, simply restart your PowerShell prompt/ISE, OR, Change the name of the public class:

Code1x

Add for example a number after, so that the class is called: ProvisionOneDrive1, then 2 and so on.

2. Nothing happens, no OneDrive shows up?

Verify all your values, then execute the command again. Remember though, that the time it takes for a site to show up may vary and can take up to 5 minuter PER SITE. Wait a moment longer, try it again

If you have the wrong address when verifying, you will see either of these pages depending on the URL used:

A link like:
https://donkeymind-my.sharepoint.com/personal/testuser4_donkeymind_onmicrosoft_com/_layouts/start.aspx#/Documents/Forms/All.aspx?LoadProfile=TRUE

Error1

A link like:
https://donkeymind-my.sharepoint.com/personal/testuser4_donkeymind_onmicrosoft_com

error2

404 could also just mean that the site is in queue and has not been provisioned yet.

References and Credits


Stefan Gossners old post: Using CSharp (C#) code in Powershell scripts
http://blogs.technet.com/b/stefan_gossner/archive/2010/05/07/using-csharp-c-code-in-powershell-scripts.aspx

Office365 Developer Patterns & Practices/Office App Model Samples
http://officeams.codeplex.com/

TechNet Add-Type
http://technet.microsoft.com/en-us/library/hh849914.aspx

Credits & many thanks to

Kimmo Forss, Microsoft

Jörgen Andersson, Xperta

All the contributors of Office AMS

Always, Mattias Gutke at CAG

Stefan Gossner, Microsoft (Blog) for that short and concise post written a few years back.

My love for putting up with me while solving this problem and writing this post!

SP2013logo

_________________________________________________________

Enjoy!

Regards

Twitter | Technet Profile | LinkedIn