Link to home
Start Free TrialLog in
Avatar of Network Zero
Network ZeroFlag for United States of America

asked on

Export Contacts from office 365 to excel using powershell

I found two scripts that I can use to export contacts from office 365 but they don't seam to able to let me just sign in as the tenant admin or global admin to just be able to pipe all the accounts - I have to do this for 40 accounts!

I found this code from tech net

<#
The sample scripts are not supported under any Microsoft standard support 
program or service. The sample scripts are provided AS IS without warranty  
of any kind. Microsoft further disclaims all implied warranties including,  
without limitation, any implied warranties of merchantability or of fitness for 
a particular purpose. The entire risk arising out of the use or performance of  
the sample scripts and documentation remains with you. In no event shall 
Microsoft, its authors, or anyone else involved in the creation, production, or 
delivery of the scripts be liable for any damages whatsoever (including, 
without limitation, damages for loss of business profits, business interruption, 
loss of business information, or other pecuniary loss) arising out of the use 
of or inability to use the sample scripts or documentation, even if Microsoft 
has been advised of the possibility of such damages.
#>

#requires -Version 2

#Import Localized Data
Import-LocalizedData -BindingVariable Messages
#Load .NET Assembly for Windows PowerShell V2
Add-Type -AssemblyName System.Core

$webSvcInstallDirRegKey = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Exchange\Web Services\2.0" -PSProperty "Install Directory" -ErrorAction:SilentlyContinue
if ($webSvcInstallDirRegKey -ne $null) {
	$moduleFilePath = $webSvcInstallDirRegKey.'Install Directory' + 'Microsoft.Exchange.WebServices.dll'
	Import-Module $moduleFilePath
} else {
	$errorMsg = $Messages.InstallExWebSvcModule
	throw $errorMsg
}

Function New-OSCPSCustomErrorRecord
{
	#This function is used to create a PowerShell ErrorRecord
	[CmdletBinding()]
	Param
	(
		[Parameter(Mandatory=$true,Position=1)][String]$ExceptionString,
		[Parameter(Mandatory=$true,Position=2)][String]$ErrorID,
		[Parameter(Mandatory=$true,Position=3)][System.Management.Automation.ErrorCategory]$ErrorCategory,
		[Parameter(Mandatory=$true,Position=4)][PSObject]$TargetObject
	)
	Process
	{
		$exception = New-Object System.Management.Automation.RuntimeException($ExceptionString)
		$customError = New-Object System.Management.Automation.ErrorRecord($exception,$ErrorID,$ErrorCategory,$TargetObject)
		return $customError
	}
}

Function Connect-OSCEXOWebService
{
	#.EXTERNALHELP Connect-OSCEXOWebService-Help.xml

    [cmdletbinding()]
	Param
	(
		#Define parameters
		[Parameter(Mandatory=$true,Position=1)]
		[System.Management.Automation.PSCredential]$Credential,
		[Parameter(Mandatory=$false,Position=2)]
		[Microsoft.Exchange.WebServices.Data.ExchangeVersion]$ExchangeVersion="Exchange2010_SP2",
		[Parameter(Mandatory=$false,Position=3)]
		[string]$TimeZoneStandardName,
		[Parameter(Mandatory=$false)]
		[switch]$Force
	)
	Process
	{
        #Get specific time zone info
        if (-not [System.String]::IsNullOrEmpty($TimeZoneStandardName)) {
            Try
            {
                $tzInfo = [System.TimeZoneInfo]::FindSystemTimeZoneById($TimeZoneStandardName)
            }
            Catch
            {
                $PSCmdlet.ThrowTerminatingError($_)
            }
        } else {
            $tzInfo = $null
        }

		#Create the callback to validate the redirection URL.
		$validateRedirectionUrlCallback = {
            param ([string]$Url)
			if ($Url -eq "https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml") {
            	return $true
			} else {
				return $false
			}
        }	
	
		#Try to get exchange service object from global scope
		$existingExSvcVar = (Get-Variable -Name exService -Scope Global -ErrorAction:SilentlyContinue) -ne $null
		
		#Establish the connection to Exchange Web Service
		if ((-not $existingExSvcVar) -or $Force) {
			$verboseMsg = $Messages.EstablishConnection
			$PSCmdlet.WriteVerbose($verboseMsg)
            if ($tzInfo -ne $null) {
                $exService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService(`
				    		 [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$ExchangeVersion,$tzInfo)			
            } else {
                $exService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService(`
				    		 [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$ExchangeVersion)
            }
			
			#Set network credential
			$userName = $Credential.UserName
            $password = $Credential.GetNetworkCredential().Password
			$exService.Credentials = New-Object System.Net.NetworkCredential($userName,$password)
			Try
			{
				#Set the URL by using Autodiscover
				$exService.AutodiscoverUrl($userName,$validateRedirectionUrlCallback)
				$verboseMsg = $Messages.SaveExWebSvcVariable
				$PSCmdlet.WriteVerbose($verboseMsg)
				Set-Variable -Name exService -Value $exService -Scope Global -Force
			}
			Catch [Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverRemoteException]
			{
				$PSCmdlet.ThrowTerminatingError($_)
			}
			Catch
			{
				$PSCmdlet.ThrowTerminatingError($_)
			}
		} else {
			$verboseMsg = $Messages.FindExWebSvcVariable
            $verboseMsg = $verboseMsg -f $exService.Credentials.Credentials.UserName
			$PSCmdlet.WriteVerbose($verboseMsg)            
		}
	}
}

Function Export-OSCEXOContact
{
	#.EXTERNALHELP Export-OSCEXOContact-Help.xml

	[cmdletbinding()]
	Param
	(
		#Define parameters
		[Parameter(Mandatory=$true,Position=1)]
		[string]$Path,
		[Parameter(Mandatory=$false,Position=2)]
		[int]$PageSize=100
	)
    Begin
    {
        #Verify the existence of exchange service object
        if ($exService -eq $null) {
			$errorMsg = $Messages.RequireConnection
			$customError = New-OSCPSCustomErrorRecord `
			-ExceptionString $errorMsg `
			-ErrorCategory NotSpecified -ErrorID 1 -TargetObject $PSCmdlet
			$PSCmdlet.ThrowTerminatingError($customError)
        }
    }
    Process
    {
        #Dictionary Properties
        $dicProperties = "EmailAddresses","ImAddresses","PhoneNumbers","PhysicalAddresses"
        $emailAddressKeys = @()
        $imAddressKeys = @()
        $phoneNumberKeys = @()
        $physicalAddressKeys = @()

        #Get keys from Dictionary Properties
        [Microsoft.Exchange.WebServices.Data.EmailAddressKey]    | Get-Member -Static -MemberType Property | %{$emailAddressKeys    += $_.Name}
        [Microsoft.Exchange.WebServices.Data.ImAddressKey]       | Get-Member -Static -MemberType Property | %{$imAddressKeys       += $_.Name}
        [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]     | Get-Member -Static -MemberType Property | %{$phoneNumberKeys     += $_.Name}
        [Microsoft.Exchange.WebServices.Data.PhysicalAddressKey] | Get-Member -Static -MemberType Property | %{$physicalAddressKeys += $_.Name}

        #Prepare command to export contacts
        $stringBuilder = New-Object System.Text.StringBuilder
        $stringBuilder.AppendLine('$findResults.Items | Select-Object -Property *, `') | Out-Null

        foreach ($emailAddressKey in $emailAddressKeys) {
            $stringBuilder.AppendLine("@{Name='$emailAddressKey';Expression={`$_.EmailAddresses['$emailAddressKey']}}, ``") | Out-Null
        }

        foreach ($imAddressKey in $imAddressKeys) {
            $stringBuilder.AppendLine("@{Name='$imAddressKey';Expression={`$_.ImAddresses['$imAddressKey']}}, ``") | Out-Null
        }

        foreach ($phoneNumberKey in $phoneNumberKeys) {
            $stringBuilder.AppendLine("@{Name='$phoneNumberKey';Expression={`$_.PhoneNumbers['$phoneNumberKey']}}, ``") | Out-Null
        }

        foreach ($physicalAddressKey in $physicalAddressKeys) {
            if ($physicalAddressKey -ne "Other") {
                $stringBuilder.AppendLine("@{Name='$physicalAddressKey';Expression={`$_.PhoneNumbers['$physicalAddressKey']}}, ``") | Out-Null
            } else {
                $stringBuilder.AppendLine("@{Name='$physicalAddressKey';Expression={`$_.PhoneNumbers['$physicalAddressKey']}} ``") | Out-Null
            }
        }

        $stringBuilder.AppendLine('| Select-Object -Property * -ExcludeProperty "EmailAddresses","ImAddresses","PhoneNumbers","PhysicalAddresses" `') | Out-Null
        $stringBuilder.AppendLine('| Export-Csv -Path $Path -NoTypeInformation -Encoding UTF8') | Out-Null

        $cmd = $stringBuilder.ToString()

        #Define ItemView
        $itemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView($PageSize)

        #Bind to contact folder
        $contactFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exService,`
                         [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts)
        
        #Find contacts in the contact folder
        do
        {
            $findResults = $contactFolder.FindItems($itemView)
			$itemView.Offset += $PageSize
        } while ($findResults.MoreAvailable)

        #Export contact
        try
        {
            Invoke-Expression -Command $cmd
        }
        catch
        {
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }
    End {}
}

Export-ModuleMember -Function "Connect-OSCEXOWebService","Export-OSCEXOContact"

Open in new window


The same people created both scripts - They said I should be able to code script 2 into script 1 and have it use "impersonation" in order to able to accomplish this.

#Save appointment to the default Calendar folder 
Try 
{ 
    if ($UseImpersonation) { 
        $impersonationUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId(` 
                               [Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,` 
                                ,$userSMTPAddress) 
        $exService.ImpersonatedUserId = $impersonationUserId 
        $newAppointment.Save([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,` 
                             [Microsoft.Exchange.WebServices.Data.SendInvitationsMode]::SendToNone) 
  
        #Clear ImpersonationUserId 
        $exService.ImpersonatedUserId = $null 
    } else { 
        $folderId = New-Object Microsoft.Exchange.WebServices.Data.FolderId(` 
                   [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,` 
                   $userSMTPAddress) 
        $newAppointment.Save($folderId, [Microsoft.Exchange.WebServices.Data.SendInvitationsMode]::SendToNone) 
    } 
} 
Catch 
{ 
    $PSCmdlet.WriteError($_) 
}

Open in new window


Here's script one: https://gallery.technet.microsoft.com/office/Export-Contacts-from-OWA-9f8cc0f2#content
There's script two: https://gallery.technet.microsoft.com/scriptcenter/Create-Appointments-for-779b55ad

Thanks in advanced - I tried editing it for 2 hours but failed.
SOLUTION
Avatar of Vasil Michev (MVP)
Vasil Michev (MVP)
Flag of Bulgaria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Network Zero

ASKER

the 2nd script has a function of "Impersonate" that would allow me to sign into as the admin and then export just using one account

I want to take the 2nd script and put it into the first one so I can use that in the export contact script.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I've requested that this question be deleted for the following reason:

Not enough information to confirm an answer.
closed.