Follow me on Twitter @AntonioMaio2

Tuesday, November 14, 2017

A Beginner's Guide to Administering Office 365 with PowerShell

With Office 365 PowerShell, you can manage Office 365 for your organization using commands and scripts that streamline your day to day work. Microsoft provides several easy to use admin centers to help manage Office 365. However, whether you’re an Office 365 administrator yourself or a service owner for Office 365 in your organization (working with other administrators), you’ll quickly find that you need to go beyond the capabilities that these admin centers provide. PowerShell can help you automate tasks so that they are easily repeatable, it can help you script management tasks so that they are automatically performed on a schedule and it can help you quickly output large amounts of data about your Office 365 environment. As well, some Office 365 settings are only manageable using PowerShell, with no UX provided. In this session, you’ll learn how to get started with Office 365 PowerShell and how to quickly become productive with it, making you more productive and empowered as you manage your Office 365 environment.

Thank you to those that attended my session today on this topic at SPTechCon DC! You were a great crowd with lots of great questions.

My updated slides can be found here:

Enjoy.
-Antonio

Monday, November 6, 2017

Set a SharePoint Online Managed Metadata (Taxonomy) Field Value on a Document or Item

Just last week I had an interesting little project I was helping a client with where we needed to use PowerShell to set 2 metadata field values for a document in a SharePoint Online Document Library. I've done this before many times. However, the challenge here was that the metadata fields were managed metadata fields, configured as part of a corporate taxonomy using the Managed Metadata Service.

My preferred method to accomplish this would have been SharePoint PnP PowerShell module using Set-PnPTaxonomyFieldValue (reference: https://msdn.microsoft.com/en-us/pnp_powershell/setpnptaxonomyfieldvalue). Unfortunately, for various reasons that wasn't possible in my client's environment so we had to resort to writing the PowerShell script ourselves.

As many of you know, you cannot set managed metadata field values the same way you would a regular metadata field. In searching the web for some guidance on which methods to use, I found that out of the blogs and documentation available, much of it was either incomplete or incorrect. So, with the help of a few kind folks on Twitter, namely Erwin Van Hunen (@erwinvanhunen) and Chris Kent (@thechriskent), I was able to work out a solution. I'd like to share here how that was accomplished so that others might benefit from Erwin's and Chris' assistance and from my experience. I'll try to be as complete as possible here, so that you have a full solution.

An important step is to download and install the latest SharePoint Online Client Components SDK. At the time of publishing, Microsoft had recently released a new version for September 2017, which can be downloaded from here: https://www.microsoft.com/en-ca/download/details.aspx?id=42038. This must be installed on the computer that will be running this script. Now onto our PowerShell code:

First, we'll set some basic variables:
$UserCredentials = Get-Credential
$webUrl = "https://mytenant.sharepoint.com/sites/mySiteCol/mySubsite/"
$listName = "MyList"
$itemToEdit = "/sites/mySiteCol/mySubsite/MyList/MyDocument.docx"
$termGroupName = "My Term Group"
$targetField1Name = "Field 1"
$targetField2Name = "Field 2"
$targetField1Value = "Value 1"
$targetField2Value = "Value 2"

Now, we setup our paths to the SharePoint Online Client Components SDK. Specifically, notice that we are using Microsoft.SharePoint.Client.Taxonomy.dll. These are the default paths where these DLLs should be installed on your computer.
$sCSOMPath = "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI"
$sCSOMRuntimePath=$sCSOMPath +  "\Microsoft.SharePoint.Client.Runtime.dll"
$sCSOMTaxonomyPath=$sCSOMPath +  "\Microsoft.SharePoint.Client.Taxonomy.dll"
$sCSOMPath=$sCSOMPath +  "\Microsoft.SharePoint.Client.dll"
Add-Type -Path $sCSOMPath
Add-Type -Path $sCSOMRuntimePath
Add-Type -Path $sCSOMTaxonomyPath

Next, we create our context and authenticate:
$context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl)
$context.AuthenticationMode = [Microsoft.SharePoint.Client.ClientAuthenticationMode]::Default
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserCredentials.UserName, $UserCredentials.Password)
$context.Credentials = $credentials

Now, we retrieve our managed metadata fields from our Document Library and create our Taxonomy fields:
#get the collection of lists in our site and find our list by name
$lists = $context.web.Lists
$context.Load($lists)
$list = $lists.GetByTitle($listName)

#get our target field objects
$field1 = $list.Fields.GetByInternalNameOrTitle($targetField1Name)
$field2 = $list.Fields.GetByInternalNameOrTitle($targetField2Name)
$context.Load($field1)
$context.Load($field2)
$Context.ExecuteQuery()

$txField1 =[Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.Taxonomy.TaxonomyField]).Invoke($Context, $field1)
$txField2 = [Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.Taxonomy.TaxonomyField]).Invoke($Context, $field2)

Next, we create a session with the Managed Metadata Service and retrieve the terms we wish to set. This allows us to validate that the term values we're trying to set actually do exist in the term store.
$session = $spTaxSession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context)
$session.UpdateCache();
$context.Load($session)

$termStores = $session.TermStores
$context.Load($termStores)
$Context.ExecuteQuery()

$termStore = $TermStores[0]
$context.Load($termStore)
$Context.ExecuteQuery()

$groups = $termStore.Groups
$context.Load($groups)
$Context.ExecuteQuery()

$groupReports = $groups.GetByName($termGroupName)
$context.Load($groupReports)
$context.ExecuteQuery()

$termSetField1 = $groupReports.TermSets.GetByName($targetField1Name)
$termSetField2 = $groupReports.TermSets.GetByName($targetField2Name)
$context.Load($termSetField1)
$context.Load($termSetField2)
$context.ExecuteQuery()

$termsField1 = $termSetField1.GetAllTerms()
$termsField2 = $termSetField2.GetAllTerms()
$context.Load($termsField1)
$context.Load($termsField2)
$context.ExecuteQuery()

foreach($term1 in $termsField1)
{
    if($term1.Name -eq $targetField1Value)
    {
        Write-Host "Found our term in the termset: $($term1.Name) with id: $($term1.id)"
        break
    }
}

foreach($term2 in $termsField2)
{
    if($term2.Name -eq $targetField2Value)
    {
        Write-Host "Found our term in the termset: $($term2.Name) with id: $($term2.id)"
        break
    }
}

if(($term1.Name -ne $targetField1Value) -or ($term2.Name -ne $targetField2Value))
{
    Write-Host "Missing term set values.  Double check that the values you are trying to set exit in the termstore. Exiting."
    exit
}

Finally, find the item we want to edit, check it out (if file checkout is required), update the taxonomy metadata fields and check the document back in:

#get all items in our list
$listItems = $list.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$context.Load($listitems)
$context.ExecuteQuery()  
$itemFound = $false

foreach($item in $listItems)  
{        
    If($($item["FileRef"]) -eq $ItemToEdit)
    {
        Write-Host "Found our item..."
        $itemFound = $true

        $context.Load($item.File) 
        $context.ExecuteQuery();

        #Checkout the item and assign the content type to the document
        if($item.File.CheckOutType -eq "None")
        {
            $item.File.CheckOut();
            Write-Host "Item has been checked out"
        }      

        #create a brand new field and set our Year managed metadata field
        #you cannot simply reuse the term object you found above in the term store
        $txField1value = New-Object Microsoft.SharePoint.Client.Taxonomy.TaxonomyFieldValue 
        $txField1value.Label = $term1.Name           # the label of your term 
        $txField1value.TermGuid = $term1.Id          # the guid of your term 
        $txField1value.WssId = -1                    # the default value

        $txField1.SetFieldValueByValue($item,$txField1value)

        #create a brand new field and set our Period managed metadata field
        #you cannot simply reuse the term object you found above in the term store
        $txField2value = New-Object Microsoft.SharePoint.Client.Taxonomy.TaxonomyFieldValue 
        $txField2value.Label = $term2.Name           # the label of your term 
        $txField2value.TermGuid = $term2.Id          # the guid of your term 
        $txField2value.WssId = -1                    # the default value

        $txField2.SetFieldValueByValue($item,$txField2value)

        #update the item with all changes
        $item.Update()
        $item.File.CheckIn("Item metadata values have been updated", 1)  

        Write-Host "Item has been checked in with updated metadata values"

        $context.ExecuteQuery();

        break;
    }
}

if($itemFound)
{
    Write-Host "Updating the item's metadata is complete."
}
else
{
    Write-Host "Item not found: $itemToEdit"
}

I'm sure there are ways to make some of this more efficient, and of course the most efficient method of all would be to use the SharePoint PnP PowerShell module using Set-PnPTaxonomyFieldValue (reference: https://msdn.microsoft.com/en-us/pnp_powershell/setpnptaxonomyfieldvalue) if you're environment allows it at the time. However, I wanted to paint a complete picture of what's involved in building such a script if you have to create it from scratch in PowerShell yourself.

Enjoy.
-Antonio

Monday, August 14, 2017

Raise Your Office 365 Secure Score

Thanks to everyone that attended our webinar last week on Office 365 Secure Score.

For many organizations moving to Office 365 or other Cloud services, the concepts of security, compliance and risk are complex. They require learning about how these security concepts have changed and how they’re now implemented in a Cloud first, Mobile friendly world. They often require working with security experts to evaluate the current state of the security for the Cloud application that you’re concerned about… and determining which security capabilities and features you are and are not yet making use of.

When we worked in on premise server environments, things seemed almost easier in some ways because our server farms which hosted Exchange, SharePoint, Skype for Business and so on were all within our corporate networks. They were more under our control, and we felt some level of comfort from being able to stop internet traffic at the network boundary, usually through our firewalls or gateways.
Regardless of how truly secure our not our networks and applications in fact were, we often gained some comfort from this boundary.

With the advent of Cloud computing, with the desire to do work on a whole range of Mobile devices, even our own personal devices, and with the desire to access our services for work from anywhere in the world, moving to services which are hosted on servers and in data centers that are not under our control often feels like we’ve lost that comfort… that assurance that we’re controlling the security of our critical IT services, or it feels that we’ve given the management of our security over to someone else (that we can’t see, that we can’t talk to and that we don’t know).

When, in actuality, often services like Office 365 are more secure than we could have ever hoped to deploy in our own environments… often we have more control over how our services are secured than we’ve ever had. We often just aren’t aware yet of the security benefits that come out of box with Office 365, and we’re not aware of the security capabilities that are available for us to use.

Office 365 Secure Score is a security analytics tool from Microsoft that comes with your Office 365 subscription. Its built to help us understand and navigate all of the security options that are available to us in Office 365.

It’s a relatively new feature from Microsoft, released early this year. Its purpose is really to:
  • Help us understand our current security posture
  • Help us understand which security features we are using and not yet using
  • Help us understand the impact of rolling out new security features to our end users and administrators, and what the security benefits are to us
  • Help us understand how we can improve our security posture, and it even tracks our progress over time

My presentation slides are available here:


Please reach out and let me know if you have any questions.

Enjoy.
-Antonio

Monday, July 31, 2017

SPSNYC: Office 365 Security - MacGyver, Ninja or SWAT Team

Thanks to everyone that attended my session at SharePoint Saturday NYC this past weekend. We had a great group in the room and some really good questions.

This presentation was designed to address 3 different roles that may be charged with the responsibility of managing and securing their organization's Office 365 environment:
  • MacGyver - or the IT Team Member that's self-trained, has been handed Office 365 and told to manage and secure it for the organization
  • Ninja - or the Security Expert who is formally trained, knows their stuff when it comes to information security and was given responsibility for securing their organization's Office 365 environment
  • SWAT Team - or the Information Security Team comprised of multiple security experts, with distributed roles and responsibilities

You can find the slides from my presentation here:

Please feel free to reach out to me if you have any questions at all.

Enjoy.
-Antonio

Tuesday, May 16, 2017

SharePoint Virtual Summit 2017 - Share with Confidence! #SPSummit


Today Microsoft hosted one of the most highly anticipated SharePoint events:
SharePoint Virtual Summit!

Many of us have been looking forward to this event for weeks and today's event did not disappoint. I tend to focus on the security and governance capabilities when it comes to SharePoint and Office 365, and one of the lines in today's #SPSummit that struck me most was the phrase 'Share with Confidence'! Those of us that work with information every day, even those whose job it is to secure information or oversee the security of information systems, we want to share information with others. Information sharing is a key principle of any collaboration solutions like SharePoint Online. However, we want to be confident that we're sharing with the right people, under the right conditions, and that the information we share is still being protected. Some of today's SharePoint Online announcements really do help improve the Sharing experience in Office 365 so that we can Share with Confidence!


Here are some of my favorite announcements from today that I believe help us better secure our content and share it confidently with others...

Monday, April 10, 2017

Office 365 Audit Log Data - How long are my logs retained for?

I'm a big fan of the Unified Audit Log in Office 365. Its a fantastic tool for monitoring user activity for suspicious behavior, getting automated alerts when particular activities occur and investigating data breaches. I'm talking about the central logging facility within Office 365 that collects log data from many Office 365 workloads, and can be searched in the Office 365 Security and Compliance Center: Go to https://protection.office.com > Click Search & Investigate > Click Audit Log Search.

I often get asked the question, how long are Office 365 log entries stored or retained for? There are several answers...

Monday, April 3, 2017

Security Controls in the OneDrive for Business Admin Center

Microsoft recently added a new and extremely helpful Admin Center to Office 365 specifically for OneDrive for Business.

In terms of additional security controls this is a great addition because it allows us to more easily control access and sharing specifically in OneDrive for Business, and not just SharePoint Online. Many of the external sharing settings overlap with those already available for SharePoint Online sites. However, this is a very good start and we look forward to seeing more capabilities added over time to help us control and manage how our users share content with those outside of our organizations.

For now, let's take a closer look at the security controls now available for OneDrive for Business..

Friday, February 10, 2017

A Practical Overview of Office 365 Advanced Security Management - Part 3
Security Policies

Microsoft Office 365 Advanced Security Management is a capability within the Office 365 platform that allows organizations to go above and beyond the typical security management features, helping them to better secure users, permissions, content and apps. This multi-part blog series will look at how to use the features that make up Advanced Security Management (ASM) and share technical details that will help you to understand the benefits of these robust tools.

In part 1, we provided an Introduction to Advanced Security Management and shared technical information about how it works with the Office 365 Unified Audit Log: A Practical Overview of Office 365 Advanced Security Management - Part 1.

In part 2, we reviewed ASM's Productivity App Discovery Dashboard in depth to see how log files can be imported, how to create reports & interpret the analysis results and how you can try it with built-in sample logs: A Practical Overview of Office 365 Advanced Security Management - Part 2.

In part 3, we review the Security Policies that may be configured to control, monitor and alert on specific user behaviors.

Wednesday, January 25, 2017

A Practical Overview of Office 365 Advanced Security Management - Part 2
Productivity App Discovery Dashboard

In the middle of 2016, Microsoft released the first version of Office 365 Advanced Security Management, a new capability within the Office 365 platform that allows organizations to go above and beyond the typical security management features, helping them to better secure users, permissions, content and apps. This multi-part blog series will look at how to use the features that make up Advanced Security Management (ASM) and share technical details that will help you to understand the benefits of these robust tools.

In part 1, we introduced Advanced Security Management and shared technical information about how it works with the Office 365 Unified Audit Log:
A Practical Overview of Office 365 Advanced Security Management - Part 1.


In part 2, we review the Productivity App Discovery Dashboard capability of ASM to see how log files are imported, how to create reports and review the results of ASM's analysis of those logs, and how you can try it out with some built-in sample logs.