Thursday, 22 June 2017

List All Checked Out Files Using PowerShell

As a SharePoint administrator, if you are in need to find and get the list of all checked out files from a SharePoint document library, we can easily retrieve it by using client object model (CSOM) in Powershell.

The following Powershell script find and lists all the documents in a SharePoint Online document library which are checkout by current user and all other users.
#Add required references to SharePoint client assembly to use CSOM 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")  
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles")
  
$siteUrl="https://spotenant.sharepoint.com/sites/testsite"
$UserName = "admin@spotenant.onmicrosoft.com"
$SecPwd = $(ConvertTo-SecureString 'adminPassword' -asplaintext -force) 
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) 
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecPwd) 
$ctx.credentials = $credentials
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()
$list=$ctx.Web.Lists.GetByTitle("Documents")
$ctx.Load($list)
$ctx.ExecuteQuery()
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml ="<View Scope='RecursiveAll' />";
$allItems=$list.GetItems($camlQuery)
$ctx.Load($allItems)
$ctx.ExecuteQuery()
 
foreach($item in $allItems)
{

$file = $ctx.Web.GetFileByServerRelativeUrl($item["FileRef"]);
$ctx.Load($file)
$ctx.Load($file.ListItemAllFields)
$CheckedOutByUser=$file.CheckedOutByUser     
$ModifiedBy=$file.ModifiedBy
$ctx.Load($CheckedOutByUser)
$ctx.Load($ModifiedBy)
try
{
$ctx.ExecuteQuery()
if($CheckedOutByUser.LoginName -ne $null){
Write-Host "##############"
Write-Host "File:" $file.Name
Write-Host "Url:" $item["FileRef"]
Write-Host "CheckedOutBy:" $CheckedOutByUser.LoginName
Write-Host "Last Modified By:" $ModifiedBy.LoginName
Write-Host "##############"
Write-Host ""
}}
catch{}
}
In the above powershell script first we are retrieving all the files from library and check every file if it is checked out by user or not, this process may time consuming in large document library, so alternatively we can use filter in caml query itself and retrieve checked out files alone.
#Add required references to SharePoint client assembly to use CSOM 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")  
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles")
  
$siteUrl="https://spotenant.sharepoint.com/sites/testsite"
$UserName = "admin@spotenant.onmicrosoft.com"
$SecPwd = $(ConvertTo-SecureString 'adminPassword' -asplaintext -force)
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) 
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecPwd) 
$ctx.credentials = $credentials
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()
$list=$ctx.Web.Lists.GetByTitle("Documents")
$ctx.Load($list)
$ctx.ExecuteQuery()
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml ="<View Scope='RecursiveAll'><Query><Where><IsNotNull><FieldRef Name='CheckoutUser' /></IsNotNull></Where></Query></View>";
$allItems=$list.GetItems($camlQuery)
$ctx.Load($allItems)
$ctx.ExecuteQuery()
 
foreach($item in $allItems)
{
$file = $ctx.Web.GetFileByServerRelativeUrl($item["FileRef"]);
$ctx.Load($file)
$CheckedOutByUser=$file.CheckedOutByUser     
$ModifiedBy=$file.ModifiedBy
$ctx.Load($CheckedOutByUser)
$ctx.Load($ModifiedBy)
$ctx.ExecuteQuery()

Write-Host "##############"
Write-Host "File:" $file.Name
Write-Host "Url:" $item["FileRef"]
Write-Host "CheckedOutBy:" $CheckedOutByUser.LoginName
Write-Host "Last Modified By:" $ModifiedBy.LoginName
Write-Host "##############"
Write-Host ""
}

Wednesday, 21 June 2017

Get All List Items in Library using PowerShell with CSOM

In this article, I am going write a simple Powershell script using client object model (CSOM) to find and retrieve all files from a document library in SharePoint Online. To use csom in Powershell, we need to load the required Microsoft SharePoint Online SDK assembly files.

The below Powershell script simply load and list all the files from given document library in a SharePoint Online site. You need to replace sharepoint site url, list name and required admin credentials with your own details.
#Add required references to SharePoint client assembly to use CSOM 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")  
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles")
 
$siteUrl="https://spotenant.sharepoint.com/sites/testsite"
$UserName = "admin@spotenant.onmicrosoft.com"
$SecPwd = $(ConvertTo-SecureString 'adminPassword' -asplaintext -force) 
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) 
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecPwd) 
$ctx.credentials = $credentials
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()
$list=$ctx.Web.Lists.GetByTitle("Documents")
$ctx.Load($list)
$ctx.ExecuteQuery()
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml ="<View Scope='RecursiveAll' />";
$allItems=$list.GetItems($camlQuery)
$ctx.Load($allItems)
$ctx.ExecuteQuery()

foreach($item in $allItems)
{
Write-Host "##############"
Write-Host $item["FileRef"]
$file = $ctx.Web.GetFileByServerRelativeUrl($item["FileRef"]);
$ctx.Load($file)
$ctx.Load($file.ListItemAllFields)
$Author=$file.Author
$CheckedOutByUser=$file.CheckedOutByUser     
$ModifiedBy=$file.ModifiedBy
$ctx.Load($Author)
$ctx.Load($CheckedOutByUser)
$ctx.Load($ModifiedBy)
try
{
$ctx.ExecuteQuery()
Write-Host "File:" $file.Name 
Write-Host "Author:" $Author.LoginName
Write-Host "ModifiedBy:" $ModifiedBy.LoginName
if($CheckedOutByUser.LoginName -ne $null){
Write-Host "CheckedOutBy:" $CheckedOutByUser.LoginName
}}
catch{}
Write-Host "##############"
Write-Host ""
}
Along with file name and file relative url, the above script also retrieves useful information such as Author name of the file, modified username and if the file was checked out, it also returns the name of the user who currently checked-out the file and yet to checked-in.

Thursday, 15 June 2017

Hide Office 365 Group from GAL using Powershell

Hiding Office 365 Group from Global Address List (GAL) is one of the tedious job as there is no Admin UI to hide group mail from GAL. When you create an office 365 group it will not be hidden from GAL by default either it is public or private group. Currently Office 365 team accepted the user voice request to hide private groups from GAL by default. But for now, Powershell is the only option for Administrators to hide and show the groups from the GAL.

We can use the Exchange Online Powershell cmdlet Set-UnifiedGroup to hide group mail address from GAL. Before proceed, Connect Exchange Online Powershell module and use the following command.
Set-UnifiedGroup <group> -HiddenFromAddressListsEnabled $true
Actually we are setting the attribute HiddenFromAddressListsEnabled as true to hide group mail id from global address list. You can use the following command if you want set this property for all of your Office 365 Groups.
Get-UnifiedGroup | Set-UnifiedGroup -HiddenFromAddressListsEnabled $true
Normally you might want to hide only private groups. You can use below command to hide all the private groups from GAL:
Get-UnifiedGroup | Where-Object {$_.AccessType -eq 'Private'} | Set-UnifiedGroup -HiddenFromAddressListsEnabled $true
We can also list the groups that are disabled from address book using below powershell command:
Get-UnifiedGroup | Where-Object {$_.HiddenFromAddressListsEnabled -eq $true} | Select Alias,HiddenFromAddressListsEnabled
Hiding a Group from the GAL will only removes the availability of group in address list from external users, but it does not prevent other users to send email to the Group if they already know the address. If you want to restrict other users (other than group members) from sending message to the group, you need to set one more property - AcceptMessagesOnlyFromSendersOrMembers.
Set-UnifiedGroup <group> -AcceptMessagesOnlyFromSendersOrMembers <group>
If you want a group to accept messages from more than one group (multiple groups), you can give the group names as comma separated values in the above command.
Set-UnifiedGroup <group> -AcceptMessagesOnlyFromSendersOrMembers <group>,<group2>