Thursday, 27 October 2016

Connect-MsolService through Proxy in Powershell

Problem:

I used to connect Azure AD Powershell module using Connect-MsolService command. I can always able to successfully connect via proxy server and without proxy. But for some reason, today, I am receiving the errors Exception of type Microsoft.Online.Administration.Automation.MicrosoftOnlineException' was thrown and There was no endpoint listening at https://provisioningapi.microsoftonline.com/provisioningwebservice.svc that could accept the message when I use Connect-MsolService command.

Error Message 1:
Connect-MsolService : There was no endpoint listening at 
https://provisioningapi.microsoftonline.com/provisioningwebservice.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. 
At line:1 char:1 
+ Connect-MsolService -Credential $Livecred; 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo          : OperationStopped: (:) [Connect-MsolService], EndpointNotFoundException 
    + FullyQualifiedErrorId : System.ServiceModel.EndpointNotFoundException,Microsoft.Online.Administration.Automation 
   .ConnectMsolService
Error Message 2:
Connect-MsolService : Exception of type 'Microsoft.Online.Administration.Automation.MicrosoftOnlineException' was thrown. 
At line:1 char:1 
+ Connect-MsolService -Credential $Livecred; 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo          : OperationStopped: (:) [Connect-MsolService], MicrosoftOnlineException 
    + FullyQualifiedErrorId : Microsoft.Online.Administration.Automation.MicrosoftOnlineException,Microsoft.Online.Adm 
   inistration.Automation.ConnectMsolService 

Fix/Solution:

The problem was solved for me after configuring Powershell to use proxy authentication for Microsoft Online endpoint (https://provisioningapi.microsoftonline.com/provisioningwebservice.svc) using Invoke-WebRequest command in Powershell.
Invoke-WebRequest -Proxy http://myporxyerver:myport -ProxyUseDefaultCredentials https://provisioningapi.microsoftonline.com/provisioningwebservice.svc
After running the above command, now the Powershell uses my proxy settings to connect Microsoft Office 365.

Note: replace myporxyerver with your proxy server and myport with your proxy server port.

Tuesday, 25 October 2016

Set Office 365 User Password Never Expire using Powershell

We may have a requirement to set a password for an individual user to never expire and in some cases requirement would be set a group of user's password to never expire. We can set passwordneverexpires flag to Office 365 user by using the Azure AD powershell cmdlet Set-MsolUser.

Before porceed run the following command to connect Azure AD powershell module:
Import-Module MSOnline
$msolCred = Get-Credential
Connect-MsolService –Credential $msolCred
Run the below command to set an individual user’s password to never expire.
Set-MsolUser -UserPrincipalName user@yourdomain.onmicrosoft.com -PasswordNeverExpires $true
If you want to verify the PasswordNeverExpires setting has been applied or not, you can check it by using Get-MsolUser cmdlet.
Get-MsolUser -UserPrincipalName user@yourdomain.onmicrosoft.com | Select PasswordNeverExpires

Set Password Never Expire for Group of Users

In some situations, we may required to set specific type of user's password to never expire (i.e. users who are in same department or same office). In this case, we need to first get users by applying filter in Get-MsolUser cmdlet and pipe the results to Set-MsolUser cmdlet.
Get-MsolUser -All | Where-Object { $_.Department -like '*Admin*'} | Set-MsolUser -PasswordNeverExpires $true
You can just remove the where-object check in above command if you want to set it for all users.

Set Bulk AD Users Password Never Expire from CSV

We can import users from csv file and set passwordneverexpires setting. Consider the CSV file office365users.csv which contains set of Office 365 users with the column header UserPrincipalName.
Import-Csv 'C:\office365users.csv' | ForEach-Object {
$upn = $_."UserPrincipalName"
Set-MsolUser -UserPrincipalName $upn -PasswordNeverExpires $true;
}

Get all Users whose Password Never Expire

We can select all Azure AD users whose password never expire by using below command.
Get-MsolUser -All | Where-Object { $_.PasswordNeverExpires -eq $true} |
Select DisplayName,UserPrincipalName
Use below command to export output to csv file.
Get-MsolUser -All | Where-Object { $_.PasswordNeverExpires -eq $true} | 
Select DisplayName,UserPrincipalName |
Export-CSV "C:\\PwdNeverExpireUsers.csv" -NoTypeInformation -Encoding UTF8

Tuesday, 18 October 2016

Connecting to remote server failed with the following error message - ps.outlook.com

Problem:

I am receiving the error '[ps.outlook.com] Connecting to remote server failed with the following error message : The SSL connection cannot be established' when I try to connect remote Exchange Online powershell by using below command.
Import-Module MSOnline
$O365Cred = Get-Credential
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Cred - 
Authentication Basic -AllowRedirection
Import-PSSession $O365Session
Error Message:
[ps.outlook.com] Connecting to remote server failed with the following error message : The SSL connection cannot be established. Verify that the service on the remote host is properly 
configured to listen for HTTPS requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is 
the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig -transport:https". For more information, see the about_Re
mote_Troubleshooting Help topic.
    + CategoryInfo          : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [], PSRemotingTransportException
    + FullyQualifiedErrorId : PSSessionOpenFailed

Fix/Solution:

For me the problem was fixed after changing the Exchange Online ConnectionUri https://ps.outlook.com/powershell as https://outlook.office365.com/powershell-liveid/. The below command is working fine for me now.
Import-Module MSOnline
$O365Cred = Get-Credential
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $O365Cred -Authentication Basic -AllowRedirection
Import-PSSession $O365Session

Thursday, 13 October 2016

Check Mailbox Size and Usage Report using Powershell

In this collaborative business world mail communication is one of the best platform to share messages and files with customers and colleague. So, we often required to check mailbox size and quota for every user's mailbox. In this post, I am going write Powershell script to find mailbox size and usage status and find users who are going to reach their storage quota.

We can use the Exchange Online powershell cmdlet Get-MailboxStatistics to get mailbox size, and other mailbox related statistics data. This cmdlet will be available for both Exchange On-Premises server and Exchange Online (Office 365). Before proceed, first we need to connect Remote Exchange Online powershel module by running below command:
$LiveCred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Run the below command to get mailbox statistics for a single user.
Get-MailboxStatistics -Identity [username]
By default this command returns the DisplayName, ItemCount, StorageLimitStatus, and LastLogonTime fields for the specified user. But what we need is mailbox size, so we need to alter the command to return required fields.
Get-MailboxStatistics [username] | Select DisplayName, TotalItemSize,StorageLimitStatus, ItemCount
The field StorageLimitStatus indicates whether the user is above or below the storage limit. The field TotalItemSize shows the total size of a mailbox in bytes, we need to convert this size into MB or GB to make the value as user friendly.
Get-MailboxStatistics [username] | Select DisplayName, @{n=”Total Size (MB)”;e={[math]::Round(($_.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}}, StorageLimitStatus

Find Mailbox Size for all Office 365 users:

You can use the powershell cmdlet Get-Mailbox to get all the mailboxes and pipe the results into Get-MailboxStatistics cmdlet to get mailbox size for all users.
Get-Mailbox -ResultSize Unlimited  | Get-MailboxStatistics |
Select DisplayName, @{n=”Total Size (MB)”;e={[math]::Round(($_.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}}, StorageLimitStatus

Export Mailbox Size, Quota and Storage Limit Status Report to CSV:

The below powershell script export mailbox name, userprincipalname, current mailbox usage size (TotalItemSize), storage warning quota (IssueWarningQuota), maximum size limit (ProhibitSendQuota) and size limit status (StorageLimitStatus) to csv file
$Result=@() 
$mailboxes = Get-Mailbox -ResultSize Unlimited
$totalmbx = $mailboxes.Count
$i = 1 
$mailboxes | ForEach-Object {
$i++
$mbx = $_
$mbs = Get-MailboxStatistics $mbx.UserPrincipalName
 
Write-Progress -activity "Processing $mbx" -status "$i out of $totalmbx completed"
 
if ($mbs.TotalItemSize -ne $null){
$size = [math]::Round(($mbs.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)
}else{
$size = 0 }

$Result += New-Object PSObject -property @{ 
Name = $mbx.DisplayName
UserPrincipalName = $mbx.UserPrincipalName
TotalSizeInMB = $size
SizeWarningQuota=$mbx.IssueWarningQuota
StorageSizeLimit = $mbx.ProhibitSendQuota
StorageLimitStatus = $mbs.ProhibitSendQuota
}
}
$Result | Export-CSV "C:\\MailboxSizeReport.csv" -NoTypeInformation -Encoding UTF8

Thursday, 6 October 2016

Update User Profile Properties In SharePoint Online Using CSOM

In dynamic business need, we may required to frequently update user profile properties , such as email, manager and other business and personal information. In this article, I am going write Powershell script to set or update user profile properties programmatically using CSOM.

The Microsoft SharePoint Online SDK assembly Microsoft.SharePoint.Client.UserProfiles.dll includes the class PeopleManager and this class includes the following methods:
  • SetSingleValueProfileProperty - This method used to set a single valued property for any user. 
  • SetMultiValuedProfileProperty - This method used to update multi valued property for any user.
  • SetMyProfilePicture - This method used update current user profile picture. Users can only upload a picture to their own profile.

Update Single Value User Properties

Use the below Powershell script to update single valued user property.
#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")

$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 
 
$targetUser = "i:0#.f|membership|alexd@spotenant.onmicrosoft.com" 
#Initialize PeopleManager object
$peopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($ctx) 
# Update user's department info
$peopleManager.SetSingleValueProfileProperty($targetUser, "Department", "Sales Team") 
$ctx.ExecuteQuery() 

Update Multi Valued User Properties

Use the below Powershell script to set multi valued SharePoint user properties.
$siteUrl = "https://spotenant-admin.sharepoint.com" 

$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 
 
$targetUser = "i:0#.f|membership|alexd@spotenant.onmicrosoft.com" 
#Initialize PeopleManager object
$peopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($ctx) 
#Initialize string list to values
$propertyValues =New-Object "System.Collections.Generic.List``1[System.string]"   
# My responsibilities   
$propertyValues.Add("SharePoint")   
$propertyValues.Add("Office 365")           
$propertyValues.Add("Powershell") 
$propertyValues.Add("CSOM") 
# Update profile property
$peopleManager.SetMultiValuedProfileProperty($targetUser, "SPS-Skills", $propertyValues) 
$ctx.ExecuteQuery()