Wednesday, 28 December 2016

Create all day event using Microsoft Graph Api

I have just developed a small application to import holiday list from csv file into every Office 365 users Outlook calendar. I have already created an Azure AD Application and set the required permission "Read and write calendars in all mailboxes". I am using following graph api endpoint to post my new calendar event.
https://graph.microsoft.com/v1.0/me/events
Json Body to add new Christmas Holiday event (2016-12-25):
{  
  "originalStartTimeZone": "UTC",
  "originalEndTimeZone": "UTC",
   "Subject":"Christmas Holiday",
   "Start":{  
      "DateTime":"2016-12-25T00:00:00",
      "TimeZone":"UTC"
   },
   "End":{  
      "DateTime":"2016-12-26T00:00:00",
      "TimeZone":"UTC"
   },
"iCalUId": "iCalUId-value",
"IsAllDay":true,
} 
To a create holiday event, we need to make sure that the event should occur in whole day (12 AM to 12 PM), to achieve this we need to set the parameter isAllDay=true and we have to set the start and end properties of the event to midnight of the day when event occurs (2016-12-25T00:00:00) and midnight of the next day of the event (2016-12-26T00:00:00).

If you set the event without giving the parameter "IsAllDay":true, the event may spread over two days due to time zone problem. So, don't forgot to set the property IsAllDay as true to create all day event like holiday.

Html Javascript Code : Create Holiday Calendar Event

var jsonBody = '{  
  "originalStartTimeZone": "UTC",
  "originalEndTimeZone": "UTC",
   "Subject":"Christmas Holiday",
   "Start":{  
      "DateTime":"2016-12-25T00:00:00",
      "TimeZone":"UTC"
   },
   "End":{  
      "DateTime":"2016-12-26T00:00:00",
      "TimeZone":"UTC"
   },
"iCalUId": "iCalUId-value",
"IsAllDay":true,
}'


var httpRequest = new XMLHttphttpRequestuest();
httpRequest.open("POST", "https://graph.microsoft.com/v1.0/me/events");
httpRequest.sethttpRequestuestHeader("authorization", "Bearer " + accessToken);
httpRequest.sethttpRequestuestHeader("content-type", "application/json");
httpRequest.onload = function (e) {
    if (httpRequest.readyState === 4) {
        if (httpRequest.status === 201) {
            console.log(httpRequest.response);
        }
    }
};
httpRequest.onerror = function (e) {
    // Handle error
};
httpRequest.send(jsonBody);
Read More...

Monday, 26 December 2016

List all the OneDrive for Business users in Office 365 - Powershell

We can get the list of users with OneDrive for Business feature provisioned by using SharePoint Online UserProfileService with Powershell. As you know SharePoint is base for OneDrive as like some other services (Office 365 Groups, Planner, Teams, and etc..), so it's users basic profile information obviously will be stored in SharePoint. You can get all the SharePoint Online users using SharePoint UserProfileService and look for the Personal Space object, users who have OneDrive for Business site alone have value for this property and other users do not have this property.

Steps to Export OneDrive for Business Provisioned Users:

  • Fetch all SharePoint Online users using UserProfileService.
  • Find if OneDrive is provisioned or not.
  • Export my site collections to text file.
Note: Replace the variable <your tenant name> with your Office 365 tenant name in all the occurrences and provide your own admin credentials.
# Specify sharepoint online admin url 
$adminURL = "https://<your tenant name>-admin.sharepoint.com"

# Specify the location where the list of OneDrive sites should be saved
$LogFile = 'C:\OneDrivesites.txt'

#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")

#Provide your global admin credentials.
$UserName = "admin@<your tenant name>.onmicrosoft.com"
$SecPwd = $(ConvertTo-SecureString 'password' -asplaintext -force) 
$adminCreds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecPwd) 

# Set User Profile Service path using SPO admin URL 
$proxyaddr = "$adminURL/_vti_bin/UserProfileService.asmx?wsdl"
# Create a new webservice proxy to access UserProfileService
$UserProfileService= New-WebServiceProxy -Uri $proxyaddr -UseDefaultCredential False
$UserProfileService.Credentials = $adminCreds

# Set authentication cookies
$strAuthCookie = $adminCreds.GetAuthenticationCookie($adminURL)
$uri = New-Object System.Uri($adminURL)
$container = New-Object System.Net.CookieContainer
$container.SetCookies($uri, $strAuthCookie)
$UserProfileService.CookieContainer = $container

# Sets the first User profile, at index -1
$UserProfileResult = $UserProfileService.GetUserProfileByIndex(-1)

Write-Host "Starting- This could take a while."

$NumProfiles = $UserProfileService.GetUserProfileCount()
$i = 1

# As long as the next User profile is NOT the one we started with (at -1)...
While ($UserProfileResult.NextValue -ne -1) 
{
Write-Host "Checking profile $i of $NumProfiles" -foreground Yellow

# Look for the Personal Space object in the User Profile and retrieve it
# (PersonalSpace is the name of the path to a user's OneDrive for Business site. 
# Users who have not yet created a  OneDrive for Business site might not have this property)
$Prop = $UserProfileResult.UserProfile | Where-Object { $_.Name -eq "PersonalSpace" } 
$Url= $Prop.Values[0].Value

# If "PersonalSpace" (which we've copied to $Url) exists, log it to our file...
if ($Url) {
$siteUrl = "https://<your tenant name>-my.sharepoint.com"+ $Url
# Write OneDrive site url in console
Write-Host $Url -foreground Green
$siteUrl | Out-File $LogFile -Append -Force
}

# And now we check the next profile the same way...
$UserProfileResult = $UserProfileService.GetUserProfileByIndex($UserProfileResult.NextValue)
$i++
}
Source : https://technet.microsoft.com/en-us/library/dn911464.aspx
Read More...

Thursday, 22 December 2016

Add or Remove Members and Owners in Office 365 Group using Powershell

We can use the Add-UnifiedGroupLinks cmdlet to add members and owners to an Office 365 Group and remove members and owners from unified group using the Remove-UnifiedGroupLinks cmdlet. Both the cmdlets includes the following key parameters:

Identity – Alias, Display name, or Email address of the group
Links – Alias, Display name, or Email address of the user being added
LinkType – Members, Owners, or Subscribers

Before proceed, run the following commands to connect Exchange Online Powershell session.
$365Logon = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $365Logon -Authentication Basic -AllowRedirection
Import-PSSession $Session

Add Members and Owners to Office 365 Group

This example add the member morgan@contoso.com to the Office 365 Group named TestO365Group. We need to set the parameter LinkType as Members to add users as member.
Add-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members  –Links morgan@contoso.com
The parameter Links accept multiple values, use the following syntax: value1,value2.... to add multiple members. If the values contain spaces or otherwise require quotation marks, use the following syntax: "value1","value2",....
Add multiple users as member:
Add-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members  –Links alexw@contoso.com,alland@contoso.com
Add an user as owner: To add an user as a owner to office 365 group, first we need to add the user as a member to the specified group and then we have to add the user as owner.
Add-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members –Links morgan@contoso.com
Add-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Owners –Links morgan@contoso.com

Remove Members or Owners from Office 365 Group

This example removes the member alexd@contoso.com and alland@contoso.com from the Office 365 Group named TestO365Group..
Remove-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members –Links alexw@contoso.com ,alland@contoso.com -Confirm:$false
Remove owner: To remove an owner from the group, first you have to remove user from the LinkType Owners and remove the user from the LinkType Members.
Remove-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Owners –Links morgan@contoso.com -Confirm:$false
Remove-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members –Links morgan@contoso.com -Confirm:$false

Add or Remove members from a CSV File:

You can use the below powershell commands to add members to an office 365 group by importing users from csv file. Consider the csv file members.csv that includes the column member which holds the member identity in each row of the csv file.
Import-CSV "C:\members.csv" | ForEach-Object {
Add-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members  –Links $_.member
}

List members or owners of a group

Once we added or removed members or owners, we can use the Get-UnifiedGroupLinks cmdlet to get members or owners of a specific group. The below command lists all members of the given group.
Get-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Members
List owners of a group.
Get-UnifiedGroupLinks –Identity "TestO365Group" –LinkType Owners
Read More...

Thursday, 24 November 2016

Get all checked out files in SharePoint Library using CSOM

If you are in business need to find and get the list of all checked out documents from a sharepoint document library, we can easily achieve it by using client object model (csom) in C#.

The following C# code find and lists the files which are checkout by current user and all other users.
public static void GetAllCheckedOutFilesInLibrary() 
{ 
    string sitrUrl = "https://spotenant.sharepoint.com/sites/contoso"; 
    using (var ctx = new ClientContext(sitrUrl)) 
    { 
        //ctx.Credentials = 
        ctx.Load(ctx.Web, a => a.Lists); 
        ctx.ExecuteQuery(); 
 
        var listName = "Documents"; 
        List list = ctx.Web.Lists.GetByTitle(listName); 
        var items = list.GetItems( 
            new CamlQuery() {  
            ViewXml = @"<View Scope='RecursiveAll'><Query> 
            <Where><IsNotNull><FieldRef Name='File_x0020_Type' /></IsNotNull></Where> 
            </Query></View>"  
        }); 
        ctx.Load(items, a => a.IncludeWithDefaultProperties(item => item.File, item => item.File.CheckedOutByUser)); 
        ctx.ExecuteQuery(); 
        foreach (var item in items) 
        { 
            if (item.File.CheckOutType != CheckOutType.None) 
            { 
                Console.WriteLine("File: " + item["FileRef"].ToString().Split('/').LastOrDefault()); 
                Console.WriteLine("Checked-Out By: " + item.File.CheckedOutByUser.Title); 
                Console.WriteLine("Checked-Out User Email: " +item.File.CheckedOutByUser.Email); 
                Console.WriteLine("Last Modified: " + DateTime.Parse(item["Last_x0020_Modified"].ToString())); 
                Console.WriteLine("-----------------------"); 
                Console.WriteLine(""); 
            } 
        } 
    } 
}
In the above code first we are retrieving all the files and check every file if it is checked out or not, this method may takes some time to process large document library. So alternatively we can use filter in caml query itself and retrieve checked out files alone.
public static void GetAllCheckedOutFilesWithCamlQuery() 
{ 
    string sitrUrl = "https://spotenant.sharepoint.com/sites/contoso"; 
    using (var ctx = new ClientContext(sitrUrl)) 
    { 
        //ctx.Credentials = 
        ctx.Load(ctx.Web, a => a.Lists); 
        ctx.ExecuteQuery();  
 
        var listName = "Documents"; 
        List list = ctx.Web.Lists.GetByTitle(listName); 
        var files = list.GetItems(  
            new CamlQuery()  
            { 
            ViewXml = @"<View Scope='RecursiveAll'><Query> 
            <Where><IsNotNull><FieldRef Name='CheckoutUser' /></IsNotNull></Where> 
            </Query></View>" 
            }); 
        ctx.Load(files); 
        ctx.ExecuteQuery(); 
        foreach (var file in files) 
        { 
            Console.WriteLine("File: " + file["FileRef"].ToString().Split('/').LastOrDefault()); 
            Console.WriteLine("Checked-Out By: " + (file["CheckoutUser"] as FieldUserValue).Email); 
            Console.WriteLine("Last Modified: " + DateTime.Parse(file["Last_x0020_Modified"].ToString())); 
            Console.WriteLine("-----------------------"); 
            Console.WriteLine(""); 
        } 
    } 
} 
The above caml query retrieves documents which are checkout by all the users. If you want to get all the documents that are checked out by the current user then you can use the following caml query.
<Where>
<And>
<IsNotNull>
<FieldRef Name='CheckoutUser' />
</IsNotNull>
<Eq>
<FieldRef Name='CheckoutUser' />
<Value Type=’Integer’>
<UserID Type=’Integer’ />
</Value>
</Eq>
</And>
</Where>
Read More...

Friday, 11 November 2016

Check if Office 365 user exists or not with Powershell

In this article I am going write powershell script to check if an Office 365 user exists or not with the Azure AD Powershell cmdlet Get-MsolUser. First run the below command to connect Office 365 Powershell module.
Import-Module MSOnline
$msolCred = Get-Credential
Connect-MsolService –Credential $msolCred
The below command checks if the given user account already exists in Office 365 or not. You can retrieve user by using ObjectId or UserPrincipalName of the user.
$upn = "alexd@MyTenant.onmicrosoft.com"
$User = Get-MsolUser -UserPrincipalName $upn -ErrorAction SilentlyContinue
If ($User -ne $Null) { 
"User exists in Azure AD" 
} Else {
"User not found in Azure AD"}
You need to use the parameter -ErrorAction SilentlyContinue to skip error when user not found, otherwise you will get the error message 'Get-MsolUser : User Not Found'.

Check if multiple Azure AD accounts are exists or not

First set list of user's userprincipalname as array object and enumerate the array to find user account in Office 365.
$users = @("alexd@MyTenant.onmicrosoft.com","sarad@MyTenant.onmicrosoft.com","kevin@MyTenant.onmicrosoft.com")
foreach ($user in $users) {
$userobj = Get-MsolUser -UserPrincipalName $user -ErrorAction SilentlyContinue
If ($userobj -ne $Null) {
    Write-Host "$user already exists" -foregroundcolor "green"
} else {
    Write-Host "$user not found " -foregroundcolor "red"
}}
Read More...

Thursday, 10 November 2016

Check if AD user exists with PowerShell

In this article I am going write powershell commands to check if an Active Directory user exists or not with the AD Powershell cmdlet Get-ADUser. First run the below command to import the Active Directory module.
Import-Module ActiveDirectory
The below command checks if the given user account exists in AD or not. You can identify a user by its distinguished name (DN), GUID, SID,SamAccountName or Name.
$Name = "kevin"
$User = $(try {Get-ADUser $Name} catch {$null})
If ($User -ne $Null) { 
"User exists in AD" 
} Else {
"User not found in AD"}
You need to use try-catch block to skip error when user not found, otherwise you will receive the error message 'Get-ADUser : Cannot find an object with identity'.

Find if multiple AD users are exists or not

We can set list of user names as array object and enumerate the users to find user account in AD.
$users = @("kevin","smith","nick")
foreach ($user in $users) {
$userobj = $(try {Get-ADUser $user} catch {$Null})
If ($userobj -ne $Null) {
    Write-Host "$user already exists" -foregroundcolor "green"
} else {
    Write-Host "$user not found " -foregroundcolor "red"
}}
Read More...

Tuesday, 1 November 2016

Check if AD Users from OU are Member of a Group using Powershell

We can use the Active Directory powershell cmdlet Get-ADGroupMember to check if an AD user is member of an AD group. In this article, I am going to write powershell script to find if users of specific OU are member of a Group.

Run the following command to import Active Directory cmdlets.
Import-Module ActiveDirectory

Find AD Users from OU are Member of a Group:

We can use the cmdlet Get-ADUser to get AD users from specific OU and enumerate the users to check their membership in the particular group. We can use the parameter -Recursive with Get-ADGroupMember cmdlet to get nested group members along with direct group members. The following powershell command select users from the Organization Unit 'TestOU' and check the users are member of 'Domain Admins' group.
$users = Get-ADUser -Filter * -SearchBase "OU=TestOU,DC=TestDomain,DC=com"
$group = "Domain Admins"
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty Name
$users | ForEach-Object {
$user = $_.Name
If ($members -contains $user) {
      Write-Host "$user exists in the group"
} Else {
      Write-Host "$user not exists in the group"
}}

Check if Single User is Member of a Group:

The following powershell command find if particular single user is member of 'Domain Admins' group.
$user = "TestUser"
$group = "Domain Admins"
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty Name

If ($members -contains $user) {
      Write-Host "$user exists in the group"
 } Else {
        Write-Host "$user not exists in the group"
}
Read More...

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.
Read More...