Friday, May 7, 2021
Home Exchange Exchange System Report

Exchange System Report

The script here creates an Excel output of the entire Exchange Organization. Very useful when auditing an environment for a client. Definitely work having in your tool box for sure.


#################################################################################################################################
[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True,Position=1)]
   [string]$PowerShellServerName,
   
  [Parameter(Mandatory=$False)]
   [string]$FilePath,
   
   [switch]$BasicAuth,
   [switch]$CredsRequired
)

# Attach to Remote PowerShell on Exchange Server
$ConnectionUri = "http://" + $PowerShellServerName + "/PowerShell"
If ($CredsRequired) {
	$Creds = Get-Credential	
	$pssession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionUri -Authentication Kerberos -Credential $Creds
}
ElseIf ($BasicAuth) {
	$Creds = Get-Credential
	$ConnectionUri = $ConnectionUri.Replace("http","https")
	$pssession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionUri -Authentication Basic -Credential $Creds
}
Else {$pssession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionUri -Authentication Kerberos}

Import-PSSession $pssession

If ($FilePath) {}
Else {$FilePath = $home + "\Documents\" + (Get-OrganizationConfig).Name + "-" + $(get-date -f MM-dd-yyyy) + ".xlsx"}

$objExcel = new-Object -comobject Excel.Application  
$objExcel.visible = $True 
$objWorkbook = $objExcel.Workbooks.Add()  

Function exchOverview{
	$exchServers = Get-ExchangeServer
	#Format Sheet with name and headers
	$objWorksheet = $objWorkbook.Worksheets.Item(1)  
	$objWorksheet.Name = "Environment Overview"
	$objWorksheet.Cells.Item(1,1) = "Org Name"
	$objWorksheet.Cells.Item(1,2) = "Exchange Servers"
	$objWorksheet.Cells.Item(1,3) = "Databases"
	$objWorksheet.Cells.Item(1,4) = "Mailboxes"
	$objWorksheet.Cells.Item(1,5) = "Mail Users"
	$objWorksheet.Cells.Item(1,6) = "Contacts"
	$objWorksheet.Cells.Item(1,7) = "Distribution Groups"
	$selection = $objWorksheet.Range("A1:G1")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	$row = 2
	$objWorksheet.Cells.Item($row,1) = (Get-OrganizationConfig).Name
	$objWorksheet.Cells.Item($row,2) = (Get-ExchangeServer).count
	$objWorksheet.Cells.Item($row,3) = (Get-MailboxDatabase).count
	$objWorksheet.Cells.Item($row,4) = (Get-Mailbox -ResultSize Unlimited | Select-Object Name).count
	$objWorksheet.Cells.Item($row,5) = (Get-MailUser -ResultSize Unlimited | Select-Object Name).count
	$objWorksheet.Cells.Item($row,6) = (Get-MailContact -ResultSize Unlimited | Select-Object Name).count
	$objWorksheet.Cells.Item($row,7) = (Get-DistributionGroup -ResultSize Unlimited | Select-Object Name).count
	
	$row = 5	
	$objWorksheet.Cells.Item($row,1) = "Server Name"
	$objWorksheet.Cells.Item($row,2) = "Windows Version"
	$objWorksheet.Cells.Item($row,3) = "Windows SP"
	$objWorksheet.cells.item($row,4) = "Exchange Build"
	$objWorksheet.cells.item($row,5) = "Exchange Edition"
	$objWorksheet.cells.item($row,6) = "IP Address"
	$objWorksheet.cells.item($row,7) = "AD Site"
	$objWorksheet.cells.item($row,8) = "C: Size (GB)"
	$objWorksheet.cells.item($row,9) = "C: Free Space (GB)"
	$objWorksheet.cells.item($row,10) = "C: Percent Free (GB)"
	$ar = 'A' + $row
	$gr = 'J' + $row
	$selection = $objWorksheet.Range("${ar}:${gr}")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	#Move to the next row to begin placing data
	$row++
	foreach ($exchServer in $exchServers) {
		$ipAddresses = [System.Net.Dns]::GetHostAddresses($exchServer)
		foreach ($ipAddress in $ipAddresses) {$ip = $ipAddress.IPAddressToString}
		$WMI = Get-WmiObject Win32_OperatingSystem -ComputerName $exchServer.Name -ErrorAction SilentlyContinue
		$OSVersion = $WMI.Caption.Replace("(R)","").Replace("Microsoft ","").Replace("Enterprise","Ent").Replace("Standard","Std").Replace(" Edition","")
		$OSServicePack = $WMI.CSDVersion
		$RealName = $WMI.CSName.ToUpper()
		$disk = Get-WmiObject Win32_LogicalDisk -ComputerName $exchServer -Filter "DeviceID='c:'"
		$objWorksheet.Cells.Item($row,1) = $exchServer.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,1).Font.Size = 13
		$objWorksheet.Cells.Item($row,2) = $OSVersion
		$objWorksheet.Cells.Item($row,3) = $OSServicePack
		$objWorksheet.Cells.Item($row,4) = $exchServer.AdminDisplayVersion
		$objWorksheet.Cells.Item($row,5) = $exchServer.Edition
		$objWorksheet.Cells.Item($row,6) = $ip
		$objWorksheet.Cells.Item($row,7) = $exchServer.Site.Split('/')[3]
		$objWorksheet.Cells.Item($row,8) = "{0:N1}" -f ($disk.size / 1gb)
		$objWorksheet.Cells.Item($row,9) = "{0:N1}" -f ($disk.freeSpace / 1gb)
		$objWorksheet.Cells.Item($row,10) = "{0:P1}" -f( $disk.FreeSpace / $Disk.Size )
		$row++
	}

	$objRange = $objWorksheet.UsedRange 
	[void] $objRange.EntireColumn.Autofit()
}
Function casServers {
	#Format Sheet with name and headers
	$objWorksheet = $objWorkbook.Worksheets.Add()
	[void] $objWorksheet.Activate()
	$objWorksheet.Name = "Client Access"
	$objWorksheet.Cells.Item(1,1) = "Server Name"
	$objWorksheet.Cells.Item(1,2) = "Version"
	$objWorksheet.Cells.Item(1,3) = "AD Site"
	$objWorksheet.cells.item(1,4) = "EWS External Url"
	$objWorksheet.cells.item(1,5) = "EWS Internal URL"
	$objWorksheet.cells.item(1,6) = "OWA External URL"
	$objWorksheet.cells.item(1,7) = "OWA Internal URL"
	$objWorksheet.cells.item(1,8) = "OWA Auth Method"
	$objWorksheet.cells.item(1,9) = "ECP External URL"
	$objWorksheet.cells.item(1,10) = "ECP Internal URL"
	$objWorksheet.cells.item(1,11) = "ECP Auth Method"
	$objWorksheet.cells.item(1,12) = "OAB External URL"
	$objWorksheet.cells.item(1,13) = "OAB Internal URL"
	$objWorksheet.cells.item(1,14) = "Poll Interval"
	$objWorksheet.cells.item(1,15) = "Autodiscover URI"
	$objWorksheet.cells.item(1,16) = "Autodiscover External URL"
	$objWorksheet.cells.item(1,17) = "Autodiscover Internal URL"
	$objWorksheet.cells.item(1,18) = "OA Enabled"
	$objWorksheet.cells.item(1,19) = "OA Internal URL"
	$objWorksheet.cells.item(1,20) = "OA External URL"
	$objWorksheet.cells.item(1,21) = "OA Interal Auth Method"
	$objWorksheet.cells.item(1,22) = "OA External Auth Method"
	$objWorksheet.cells.item(1,23) = "OA IIS Auth methods enabled"
	$objWorksheet.cells.item(1,24) = "EAS External URL"
	$objWorksheet.cells.item(1,25) = "EAS Internal URL"
	$selection = $objWorksheet.Range("A1:Y1")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	#Move to the next row to begin placing data
	$row =2
	#Get list of all Exchange 2010 Client Access Servers
	$casServers = Get-ExchangeServer | where {$_.ServerRole -match "client"}
	$casServers = $casServers | Sort-Object Name
	foreach ($casServer in $casServers) {
		$EWS = Get-WebServicesVirtualDirectory -Server $casServer.Name -ADPropertiesOnly
		$OWA = Get-OwaVirtualDirectory -Server $casServer.Name -ADPropertiesOnly
		$ECP = Get-EcpVirtualDirectory -Server $casServer.Name -ADPropertiesOnly
		$CAS = Get-ClientAccessServer $casServer.Name
		$AutoDiscover = Get-AutodiscoverVirtualDirectory -Server $casServer.Name -ADPropertiesOnly
		$EAS = Get-ActiveSyncVirtualDirectory -Server $casServer.Name -ADPropertiesOnly
		$OAB = Get-OabVirtualDirectory -Server $casServer.Name -ADPropertiesOnly
		$OA = get-OutlookAnywhere -Server $casServer.Name -AdPropertiesOnly
		$OAIISAuth = $OA.IISAuthenticationMethods -join ','
		$OWAExAuth = $OWA.ExternalAuthenticationMethods -join ','
		$ECPExAuth = $ECP.ExternalAuthenticationMethods -join ','
		$objWorksheet.Cells.Item($row,1) = $casServer.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,1).Font.Size = 13
		$objWorksheet.Cells.Item($row,2) = $casServer.AdminDisplayVersion
		$objWorksheet.Cells.Item($row,3) = $casServer.Site.Split('/')[3]
		$objWorksheet.cells.item($row,4) = $EWS.ExternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,5) = $EWS.InternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,6) = $OWA.ExternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,7) = $OWA.InternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,8) = $OWAExAuth
		$objWorksheet.cells.item($row,9) = $ECP.ExternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,10) = $ECP.InternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,11) = $ECPExAuth
		$objWorksheet.cells.item($row,12) = $OAB.ExternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,13) = $OAB.InternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,14) = $OAB.PollInterval
		$objWorksheet.cells.item($row,15) = $CAS.AutoDiscoverServiceInternalUri.AbsoluteUri
		$objWorksheet.cells.item($row,16) = $Autodiscover.ExternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,17) = $AutoDiscover.InternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,18) = $CAS.OutlookAnywhereEnabled
		$objWorksheet.cells.item($row,19) = $OA.InternalHostname
		$objWorksheet.cells.item($row,20) = $OA.ExternalHostname
		$objWorksheet.cells.item($row,21) = $OA.InternalClientAuthenticationMethod
		$objWorksheet.cells.item($row,22) = $OA.ExternalClientAuthenticationMethod
		$objWorksheet.cells.item($row,23) = $OAIISAuth
		$objWorksheet.cells.item($row,24) = $EAS.ExternalUrl.AbsoluteUri
		$objWorksheet.cells.item($row,25) = $EAS.InternalUrl.AbsoluteUri
		$row++
	}
	$objRange = $objWorksheet.UsedRange 
	[void] $objRange.EntireColumn.Autofit()
}
Function hubServers {
	# Get all Exchange Transport Servers or Exchange 2013 servers (2013 doesn't have a "Transport" Role)
	$hubServers = Get-ExchangeServer | where { ($_.AdminDisplayVersion -match "15") -or ($_.ServerRole -match "Transport")}
	$hubServers = $hubServers | Sort-Object Name
	$objWorksheet = $objWorkbook.Worksheets.Add()
	[void] $objWorksheet.Activate()
	$objWorksheet.Name = "Hub Transport"
	$objWorksheet.Cells.Item(1,1) = "Server Name"
	$objWorksheet.Cells.Item(1,2) = "Version"
	$objWorksheet.Cells.Item(1,3) = "AD Site"
	$objWorksheet.Cells.Item(1,4) = "Receive Connector"
	$objWorksheet.Cells.Item(1,5) = "Bindings"
    $objWorksheet.Cells.Item(1,6) = "Remote IP Ranges"
	$objWorksheet.Cells.Item(1,7) = "Max Message Size"
	$objWorksheet.Cells.Item(1,8) = "Permission Groups"
	$objWorksheet.Cells.Item(1,9) = "Queue Database Path"
	$objWorksheet.Cells.Item(1,10) = "Queue Database Logging Path"
	$selection = $objWorksheet.Range("A1:J1")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	$row = 2
	foreach ($hubServer in $hubServers) {
		$edgeConfigPath = "\\" + $hubServer.name + "\" + $hubServer.datapath -replace (':','$') -replace ('Mailbox','Bin\EdgeTransport.exe.config')
		[xml]$transCon = Get-Content $edgeConfigPath
		$queuePath = $transCon.configuration.appsettings.add | where {$_.key -like ("QueueDatabase*path")}
		foreach ($key in $queuePath) {
			if ($key.key -match "QueueDatabasePath") {$QueueDatabasePath = $key.value}
			if ($key.key -match "QueueDatabaseLoggingPath") {$QueueDatabaseLoggingPath = $key.value}
		}
		$recConnectors = Get-ReceiveConnector -Server $hubServer.Name
		$objWorksheet.Cells.Item($row,1) = $hubServer.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,1).Font.Size = 13
		$objWorksheet.Cells.Item($row,2) = $hubServer.AdminDisplayVersion
		$objWorksheet.Cells.Item($row,3) = $hubServer.Site.Split('/')[3]
		$objWorksheet.Cells.Item($row,9) = $QueueDatabasePath
		$objWorksheet.Cells.Item($row,10) = $QueueDatabaseLoggingPath
		foreach ($recConnector in $recConnectors) {
			$bindings = $recConnector.Bindings -join ','
            $remoteIpRanges = $recConnector.RemoteIPRanges -join ','
			$row++
			$objWorksheet.Cells.Item($row,4) = $recConnector.Name
			$objWorksheet.Cells.Item($row,5) = $bindings
            $objWorksheet.Cells.Item($row,6) = $remoteIpRanges
			$objWorksheet.Cells.Item($row,7) = $recConnector.MaxMessageSize
			$objWorksheet.Cells.Item($row,8) = $recConnector.PermissionGroups
		}
		$row++
	}
	# Format worksheet for send connector information
	$row++
	$objWorksheet.Cells.Item($row,1) = "Send Connectors"
	$objWorksheet.Cells.Item($row,2) = "FQDN"
	$objWorksheet.Cells.Item($row,3) = "Max Message Size"
	$objWorksheet.Cells.Item($row,4) = "Smart Hosts"
	$objWorksheet.Cells.Item($row,5) = "Address Spaces"
	$objWorksheet.Cells.Item($row,6) = "Source Servers"
	$ar = 'A' + $row
	$gr = 'F' + $row
	$selection = $objWorksheet.Range("${ar}:${gr}")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	$sendConnectors = Get-SendConnector
	$row++
	foreach ($sendConnector in $sendConnectors) {
		$smartHosts = $sendConnector.SmartHosts -join ','
		$addressSpaces = $sendConnector.AddressSpaces -join ','
		$sourceTransportServers = $sendConnector.SourceTransportServers -join ','
		$objWorksheet.Cells.Item($row,1) = $sendConnector.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,1).Font.Size = 13
		$objWorksheet.Cells.Item($row,2) = $sendConnector.fqdn
		$objWorksheet.Cells.Item($row,3) = $sendConnector.MaxMessageSize
		$objWorksheet.Cells.Item($row,4) = $smartHosts
		$objWorksheet.Cells.Item($row,5) = $addressSpaces
		$objWorksheet.Cells.Item($row,6) = $sourceTransportServers
		$row++
	}
	$objRange = $objWorksheet.UsedRange 
	[void] $objRange.EntireColumn.Autofit()
}
Function mailboxServers {
	$mailboxServers = Get-ExchangeServer | where {$_.ServerRole -match "Mailbox"}
	$mailboxServers = $mailboxServers | Sort-Object Name
	$objWorksheet = $objWorkbook.Worksheets.Add()
	[void] $objWorksheet.Activate()
	$objWorksheet.Name = "Mailbox"
	$objWorksheet.Cells.Item(1,1) = "Server Name"
	$objWorksheet.Cells.Item(1,2) = "Version"
	$objWorksheet.Cells.Item(1,3) = "AD Site"
	$objWorksheet.Cells.Item(1,4) = "DAG"
	$objWorksheet.Cells.Item(1,5) = "DBs"
	$selection = $objWorksheet.Range("A1:E1")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	$row = 2
	foreach ($mailboxServer in $mailboxServers) {
		$MBX = Get-MailboxServer $mailboxServer.Name
		$DBS = Get-MailboxDatabase -Server $mailboxServer.Name
		$objWorksheet.Cells.Item($row,1) = $mailboxServer.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,1).Font.Size = 13
		$objWorksheet.Cells.Item($row,2) = $mailboxServer.AdminDisplayVersion
		$objWorksheet.Cells.Item($row,3) = $mailboxServer.Site.Split('/')[3]
		$objWorksheet.Cells.Item($row,4) = $MBX.DatabaseAvailabilityGroup
		$objWorksheet.Cells.Item($row,5) = $DBS.Count
		$row++
	}
	$row++
	$objWorksheet.Cells.Item($row,1) = "DAG Name"
	$objWorksheet.Cells.Item($row,2) = "Member Servers"
	$objWorksheet.Cells.Item($row,3) = "Witness Server"
	$objWorksheet.Cells.Item($row,4) = "Witness Directory"
	$objWorksheet.Cells.Item($row,5) = "Alernate Witness Server"
	$objWorksheet.Cells.Item($row,6) = "Alernate Witness Directory"
	$objWorksheet.Cells.Item($row,7) = "DAG IP Addresses"
	$objWorksheet.Cells.Item($row,8) = "DAC Enabled"
	$objWorksheet.Cells.Item($row,9) = "DAG Network"
	$objWorksheet.Cells.Item($row,10) = "Replication Enabled"
	$objWorksheet.Cells.Item($row,11) = "Subnets"
	$ar = 'A' + $row
	$gr = 'K' + $row
	$selection = $objWorksheet.Range("${ar}:${gr}")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	$row++
	$DAGS = Get-DatabaseAvailabilityGroup
	foreach ($DAG in $DAGS){
		$objWorksheet.Cells.Item($row,1) = $DAG.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,1).Font.Size = 13
		$dagServers = $DAG.Servers -join (',')
		$objWorksheet.Cells.Item($row,2) = $dagServers
		$objWorksheet.Cells.Item($row,3) = $DAG.WitnessServer
		$objWorksheet.Cells.Item($row,4) = $DAG.WitnessDirectory
		$objWorksheet.Cells.Item($row,5) = $DAG.AlternateWitnessServer
		$objWorksheet.Cells.Item($row,6) = $DAG.AlternateWitnessDirectory
		$dagAddresses = $DAG.DatabaseAvailabilityGroupIpAddresses -join (',')
		$objWorksheet.Cells.Item($row,7) = $dagAddresses
		$objWorksheet.Cells.Item($row,8) = $DAG.DatacenterActivationMode
		$dagNetworks = Get-DatabaseAvailabilityGroupNetwork | where {$_.Identity -match "$DAG"}
		foreach ($dagNetwork in $dagNetworks) {
			$objWorksheet.Cells.Item($row,9) = $dagNetwork.Identity
			$objWorksheet.Cells.Item($row,9).Font.Bold = $true
			$objWorksheet.Cells.Item($row,10) = $dagNetwork.ReplicationEnabled
			$dagNetworkSubnets = $dagNetwork.Subnets -join (',')
			$objWorksheet.Cells.Item($row,11) = $dagNetworkSubnets
			$row++
		}
		$row++
	}
	$objRange = $objWorksheet.UsedRange 
	[void] $objRange.EntireColumn.Autofit()
}
Function mailboxDatabases {
	$objWorksheet = $objWorkbook.Worksheets.Add()
	[void] $objWorksheet.Activate()
	$objWorksheet.Name = "Mailbox Databases"
	$objWorksheet.Cells.Item(1,1) = "Database"
	$objWorksheet.Cells.Item(1,2) = "Mailboxes"
	$objWorksheet.Cells.Item(1,3) = "EDB Path"
	$objWorksheet.Cells.Item(1,4) = "Log Path"
	$objWorksheet.Cells.Item(1,5) = "DB Size"
	$objWorksheet.Cells.Item(1,6) = "White Space"
	$objWorksheet.Cells.Item(1,7) = "Last Full Backup"
	$objWorksheet.Cells.Item(1,8) = "RPC Client Access Server"
	$objWorksheet.Cells.Item(1,9) = "Offline Address Book"  
	$objWorksheet.Cells.Item(1,10) = "DAG"
	$objWorksheet.Cells.Item(1,11) = "Servers"
	$objWorksheet.Cells.Item(1,12) = "Activation Preference"
	$selection = $objWorksheet.Range("A1:L1")
	$selection.Interior.ColorIndex = 15
	$selection.Borders.LineStyle = 1
	$selection.Style = "Title"
	$row = 2
	$dbs = Get-MailboxDatabase -Status | Sort name 
	foreach ($db in $dbs) {
		$mbxCount = (Get-Mailbox -Database $DB.Name -ResultSize Unlimited | Select Name).Count
		$objWorksheet.Cells.Item($row,1) = $DB.Name
		$objWorksheet.Cells.Item($row,1).Font.Bold = $true
		$objWorksheet.Cells.Item($row,2) = $mbxCount
		$objWorksheet.Cells.Item($row,3) = $DB.EDBFilePath
		$objWorksheet.Cells.Item($row,4) = $DB.LogFolderPath
		$objWorksheet.Cells.Item($row,5) = $DB.DatabaseSize
		$objWorksheet.Cells.Item($row,6) = $DB.AvailableNewMailboxSpace
		$objWorksheet.Cells.Item($row,7) = $DB.LastFullBackup
		$objWorksheet.Cells.Item($row,8) = $DB.RpcClientAccessServer
		$objWorksheet.Cells.Item($row,9) = $DB.OfflineAddressBook
		$objWorksheet.Cells.Item($row,10) = $DB.MasterServerOrAvailabilityGroup
		$objWorksheet.Cells.Item($row,11) = $DB.Servers -join (',')
		$objWorksheet.Cells.Item($row,12) = $DB.ActivationPreference -join (',')
		$row++
	}
	$objRange = $objWorksheet.UsedRange 
	[void] $objRange.EntireColumn.Autofit()
}

exchOverview
casServers
hubServers
mailboxServers
mailboxDatabases

Remove-PSSession $pssession
# Saving the file.
$objWorkbook.SaveAs($filePath)
Mark Rochesterhttps://exchange2019.com
Mark currently works in the cloud space assisting large companies to migrate from either on premises to the cloud, or cloud to cloud. His experience with Enterprise migrations spans more than 25 years which basically makes him old. However, with all the oldness creeping up he still finds technology massively exciting. Please reach out for a chat anytime you would like. 🙂

Most Popular

Recent Comments