PowerShell Todd Klindt Todd.klindt@sympraxisconsulting.com - - PowerPoint PPT Presentation
PowerShell Todd Klindt Todd.klindt@sympraxisconsulting.com - - PowerPoint PPT Presentation
PowerShell Todd Klindt Todd.klindt@sympraxisconsulting.com @toddklindt www.toddklindt.com www.toddklindt.com/ShortURL Agenda Talk about Microsofts PowerShell Talk about PNP Look at some fun scripts Official Modules There are 4
Todd Klindt
Todd.klindt@sympraxisconsulting.com
@toddklindt www.toddklindt.com
www.toddklindt.com/ShortURL
Agenda
- Talk about Microsoft’s PowerShell
- Talk about PNP
- Look at some fun scripts
Official Modules
There are 4 things to install
- Microsoft Official Office 365 PowerShell cmdlets
- Install Sign-in Assistant – 64bit
- Install MSOnline Module (v1) – GA
- Install Azure AD Module (v2) (Release or Preview)
- Install SharePoint Online Module
- Install Skype for Business Online Module
- Connect to all Office 365 Services
Before you connect
- Have to be able to Run PowerShell as an Administrator
- Have to be an Office 365 Global Administrator
- Except Exchange
- Should be running PowerShell 3.0 or later
- $PSVersionTable.PSVersion
- Recommend 5.1 on your Windows desktop
- Also consider adding PSReadLine if you are not on Win10
- Video walkthrough
- Execution policy needs to be RemoteSigned
Tangent: Talk about Passwords
- You will need your O365 username and password a lot so you have good and
bad options:
- Annoying but secure
$MyAccount = Get-Credential
- Less annoying and way, way less secure
$username = admin@company.onmicrosoft.com $password = “RightHereInPlainText” $secure = $password | ConvertTo-SecureString -AsPlainText – Force $MyAccount = New-Object System.Management.Automation.PSCredential ($username, $secure)
- Use an encrypted file
Credential Manager
- Use Credential Manager
- Install-Module credentialmanager -Scope
CurrentUser
- New-StoredCredential -Target O365 -UserName
admin@tkdemo.com -Password Password2 - Persist LocalMachine
Connect to your Azure AD Tenant
- MSOnline (v1)
# $MyAccount = Get-Credential $MyAccount = Get-StoredCredential -Target O365 Connect-MsolService -Credential $MyAccount Get-MsolUSer Get-Command -Module msonline
- AzureAD (v2)
$MyAccount = Get-Credential Connect-AzureAD -Credential $MyAccount Get-AzureADUser Get-Command -Module AzureAD
- Install-Module azuread
Fun Gotchas
Don’t Try This At Home
Connect to Skype for Business
$Skype = New-CsOnlineSession -Credential $MyAccount Import-PSSession $Skype Get-CsOnlineUser Remove-PSSession $Skype
- This one can be confusing. Remember that Skype for Business, Lync, and
Communication Server are all the same thing. The cmdlets and documentation tend to use them interchangeably.
Connect to Exchange
$Exchange = New-PSSession -ConfigurationName Microsoft.Exchange - ConnectionUri "https://outlook.office365.com/powershell-liveid/" - Credential $MyAccount -Authentication "Basic" -AllowRedirection Import-PSSession $Exchange Get-Mailbox Remove-PSSession $Exchange
- Skype and Exchange are limited to 3 sessions so always end your session.
Exchange Online
- Just a little different
- No cmdlets, uses Remoting
- Limited to three sessions
- Requires port 80
- Close out gracefully
- Remove-PSSession $Session
- Supports MFA
New-Mailbox -Alias jill -Name jill -FirstName Jill
- LastName Klindt -DisplayName "Jill Klindt" -
MicrosoftOnlineServicesID jill@tkclass.onmicrosoft.com -Password (ConvertTo- SecureString -String 'P@ssw0rd' -AsPlainText - Force) -ResetPasswordOnNextLogon $true
License Up That New Mailbox
Set-MsolUser -UserPrincipalName jill@tkclass.onmicrosoft.com –UsageLocation "US" Get-MsolAccountSku Set-MsolUserLicense -UserPrincipalName jill@tkclass.onmicrosoft.com -AddLicenses "tkclass:O365_BUSINESS_PREMIUM"
PowerShell with SharePoint Online
- Be prepared for disappointment
- Allows basic manipulation of SharePoint Online
- Users and groups
- Tenants
- Site Collections
- Hub Sites
- Multi-Geo
- Download here
- Install-Module -Name Microsoft.Online.SharePoint.PowerShell
Useful SharePoint things with all of that
<This Slide Intentionally Left Blank>
Connect to SharePoint online
Connect-SPOService -URL https://Tenant- admin.sharepoint.com
- Credential $MyAccount
Get-SPOSite Get-Command - Module Microsoft.Online.SharePoint.PowerShell
Example script
Real world example
Param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $User ) # Add the Active Directory bits and not complain if they're already there Import-Module ActiveDirectory -ErrorAction SilentlyContinue # Add the Azure Active Directory module Import-Module MSOnline
# Define AD group that is synced to AAD and is used for ODFB audience $syncgroupname = "CloudSync" $syncgroup = Get-ADGroup $syncgroupname # First, add the user to the group Add-ADGroupMember -Identity $syncgroupname -Members $User # Remind them to recompile their SharePoint audience Write-Host "You'll need to recompile your SharePoint audience to reflect the group change" # Sync up to Azure AD Start-ADSyncSyncCycle
# Now tweak the user in Azure AD, First connect Connect-MsolService -Credential (Get- StoredCredential -Target Admin) # Azure AD domain suffix $aadsuffix = (Get-MsolDomain | Where-Object - Property IsDefault -Value $true -EQ).name # Get the user $aaduser = "$user@$aadsuffix"
# Set the user's location. Without that the license will fail Set-MsolUser -UserPrincipalName $aaduser - UsageLocation “US" $license = "tkdemo:O365_BUSINESS_PREMIUM” # Set the user's license Set-MsolUserLicense -UserPrincipalName $aaduser - AddLicenses $license
Microsoft Teams!!
- Woo Hoo!
- PowerShell Support
- https://blogs.technet.microsoft.com/skypehybridguy/2017/11/07/microsoft-
teams-powershell-support/
- For automating all those Teams Tasks
- Install-Module MicrosoftTeams
Teams, Flow, and PowerApps
- Teams
- For automating all those Teams Admin Tasks
- Install-Module MicrosoftTeams
- Read all about it
- Flow and PowerApps
- For both creators and Admins
- Get list of all Flows and PowerApps
- Kind of a janky install
- Install-Module -Name Microsoft.PowerApps.PowerShell
- Install-Module -Name Microsoft.PowerApps.Administration.PowerShell
Need to add a slide on Groups
Alternative #1
The Sneaky Way: CSOM with PowerShell
- Can use the Client Side Object Model with PowerShell to do more
- Developery, be afraid
- Copy DLLs from server
- Or download SharePoint 2016
Client SDK
Top Of Script
Get-SPOweb
- Examples from:
- http://www.sharepointnutsandbolts.com/20
13/12/Using-CSOM-in-PowerShell-scripts- with-Office365.html
More Examples
Alternative #2
Patterns and Practices PowerShell (Phew!)
- More scary developer stuff
- Hidden in Github
- https://github.com/SharePoint/PnP-
PowerShell
- Adds 382 more cmdlets
- Install-Module
SharePointPnPPowerShellOnline
- Get-Command -Module
SharePointPnPPowerShellOnline
- Works with all the SharePoints
- Scoped at Site Collection
Favorites
- PnPFile
- Add-PnPFile, Copy-PnPFile
- Find-PnPFile, Get-PnPFile
- Move-PnPFile, Remove-PnPFile
- Rename-PnPFile
- Set-PnPFileCheckedIn
- Set-PnPFileCheckedOut
- PnPList
- Add, Get, Set, Remove
- Get-PnPListItem
- Set-PnPListItem
- Set-PnPGroupPermissions
- Add-PnPView
- Get-PnPField
- Restore-PnPRecycleBinItem
- Office 365 Groups
- New-PnPUnifiedGroup, Remove-
PnPUnifiedGroup
- Get-PnPUnifiedGroup, Set-
PnPUnifiedGroup
- Get-PnPUnifiedGroupMembers
- Get-PnPUnifiedGroupOwners
But my Boss HATES PnP PowerShell!
- Your boss is misinformed ☺
- Vesa Juvonen, Senior Program Manager from SharePoint Engineering and
MCM for SharePoint, is one of the main project owners
- Is scanned the same as any PowerShell Gallery Module (not at all)
- Erwin van Hunen works at RenCore
- Exceptions are approved by SharePoint Engineering team
- Will be signed with Microsoft’s key starting November 2017
- Uses the same API as web parts and other SharePoint code
- It’s Open Source
- Respects SharePoint security
- Can be more secure, as it can be more fine grained
- PnP PowerShell hits the Office 365 API a billion times a month
Examples
Upload a File
$web = https://tenant.sharepoint.com/sites/hr $folder = "Shared Documents" Connect-PnPOnline -Url $web -Credentials MeganB Add-PnPFile -Path '.\Boot fairs with Graphic design.docx' -Folder $folder
Add a Folder
Add-PnPFolder -Name "Folder 1" -Folder $folder Add-PnPFile -Path '.\Building materials licences to budget for Storytelling.docx' -Folder "$folder\Folder 1"
Get internal shared files
Connect-PnPOnline -Url $url -Credentials MeganB $doclibs = Get-PnPList -Includes DefaultViewUrl,IsSystemList | Where-Object - Property IsSystemList -EQ -Value $false | Where-Object -Property BaseType -EQ - Value "DocumentLibrary" Foreach ($doclib in $doclibs) { $docs = Get-PnPListItem -List $DocLib foreach ($doc in $docs) { if (($doc.FieldValues).SharedWithUsers -ne $null) { foreach ($user in (($doc.FieldValues).SharedWithUsers)) { Write-Output "$(($doc.FieldValues).FileRef) - $($user.email)" } } } }
Get extended file info
Connect-PnPOnline -Url $url -Credentials MeganB $doclibs = Get-PnPList -Includes DefaultViewUrl,IsSystemList | Where-Object - Property IsSystemList -EQ -Value $false | Where-Object -Property BaseType -EQ - Value "DocumentLibrary“ Foreach ($doclib in $doclibs) { $doclibTitle = $doclib.Title $docs = Get-PnPListItem -List $DocLib $docs | ForEach-Object { Get-PnPProperty -ClientObject $_ -Property File, ContentType, ComplianceInfo} foreach ($doc in $docs) { [pscustomobject]@{Library= $doclibTitle;Filename = ($doc.File).Name;ContentType = ($doc.ContentType).Name;Label = ($doc.ComplianceInfo).ComplianceTag} }
Bulk Undelete Files
Connect-PnPOnline -Url https://sadtenant.sharepoint.com/ - Credentials SadTenantAdmin $bin = Get-PnPRecycleBinItem | Where-Object -Property Leafname -Like -Value "*.jpg" | Where-Object -Property Dirname -Like -Value “Important Photos/Shared Documents/*" | Where-Object -Property DeletedByEmail -EQ -Value baduser@sadtenant.phooey $bin.count $bin | foreach
- begin { $a = 0} -Process
{Write-Host "$a - $($_.LeafName)" ; $_ | Restore-PnPRecycleBinItem -Force ; $a++ } -End { Get-Date } ($bin[20001..30000]) | foreach
- begin { $a = 0} -
Process {Write-Host "$a - $($_.LeafName)" ; $_ | Restore- PnPRecycleBinItem -Force ; $a++ } -End { Get-Date } # https://www.toddklindt.com/PoshRestoreSPOFiles
New Site and Group
- New-PnPSite -Type TeamSite -Title “Modern
Team Site" -Alias ModernTeamSite -IsPublic
The Whole Enchilada
- New-Team -DisplayName “Fancy Group" -Description “Fancy Group
made by PowerShell?" -Alias FancyGroup -AccessType Public
“Save Site as Template”
Get-PnPProvisioningTemplate -Out "customer.xml" Add-PnPListFoldersToProvisioningTemplate - Path "customer.xml" -List 'Data Storage' - Recursive Apply-PnPProvisioningTemplate -Path "customer.xml" -ClearNavigation
Copy Office 365 Group Permissions
# Set some values # use Get-PnPUnifiedGroup to get Unified Group names # Name of Unified Group whose owners and membership we want to copy $source = "Regulations" # Name of Unified Group whose owners and membership we want to populate $destination = "Empty" # Whether to overwrite Destination membership or merge them $mergeusers = $false # Check to see if PnP Module is loaded $pnploaded = Get-Module SharePointPnPPowerShellOnline if ($pnploaded -eq $false) { Write-Host "Please load the PnP PowerShell and run again" Write-Host "install-module SharePointPnPPowerShellOnline" break }
# PnP Module is loaded # Check to see if user is connected to Microsoft Graph try { $owners = Get-PnPUnifiedGroupOwners -Identity $source } catch [System.InvalidOperationException] { Write-Host "No connection to Microsoft Graph found"
- BackgroundColor Black -
ForegroundColor Red Write-Host "No Azure AD connection, please connect first with Connect-PnPOnline -Graph" - BackgroundColor Black -ForegroundColor Red break } catch [System.ArgumentNullException] { Write-Host "Group not found"
- BackgroundColor Black -ForegroundColor Red
Write-Host "Verify connection to Azure AD with Connect-PnPOnline -Graph" - BackgroundColor Black -ForegroundColor Red Write-Host "Use Get-PnPUnifiedGroup to get Unified Group names"
- BackgroundColor
Black -ForegroundColor Red break } catch { Write-Host "Some other error"
- BackgroundColor Black -ForegroundColor Red
break }
$members = Get-PnPUnifiedGroupMembers -Identity $source if ($mergeusers -eq $true) { # Get existing owners and members of Destination so that we can combine them $ownersDest = Get-PnPUnifiedGroupOwners -Identity $destination $membersDest = Get-PnPUnifiedGroupMembers -Identity $destination # Add the two lists together so we don't overwrite any existing owners
- r members in Destination
$owners = $owners + $ownersDest $members = $members + $membersDest } # Set the owners and members of Destination $owners | ForEach-Object -begin {$ownerlist = @() } -process {$ownerlist += $($_.UserPrincipalName) } $members | ForEach-Object -begin {$memberlist = @() } -process {$memberlist += $($_.UserPrincipalName) } Set-PnPUnifiedGroup -Identity $destination -Members $memberlist -Owners $ownerlist # https://www.toddklindt.com/PoshCopyO365GroupMembers
Get Your Flows
Get All the Flows
Get-AdminFlow | ForEach-Object { $ownername = (Get-MsolUser -ObjectId $_.CreatedBy.userId).DisplayName ; $owneremail = (Get-MsolUser -ObjectId $_.CreatedBy.userId).UserPrincipalName ; Write- Host $_.DisplayName, $ownername, $owneremail }
And PowerApps Apps
- Get-PowerApp