How to check what the version of your tenant is in the cloud (Office 365)

I sometimes get the question how one can verify what the version of Exchange they’re running in the cloud. Although it should be pretty obvious based on the GUI (Exchange 2010 vs. Exchange 2013) and the fact that the latter isn’t generally available yet, it could come in handy once it does. According to some sources, the release might be sooner than later.

Additionally, when you’re planning on going hybrid with the new version of Exchange in Office 365, you’ll have to make sure your tenant isn’t in the process of being upgraded and is running version 15.

To check the version, open up a PowerShell session to your Office 365 tenant and run the following command:

Get-OrganizationConfig | ft AdminDisplayVersion,IsUpgradingOrganization

With the command for connecting to Office 365 via PowerShell, that would look something like this:

$session = New-PSSession –ConnectionUri https://ps.outlook.com/powershell –AllowRedirection –Authentication Basic –Credential (Get-Credential) –ConfigurationName Microsoft.Exchange

Import-PSSession $session

Get-OrganizationConfig | ft AdminDisplayVersion,IsUpgradingOrganization

Running these commands would then lead up to a result similar to the following:

Get-OrganizationConfig | ft AdminDisplayVersion,IsUpgradingOrganization -Autosize

AdminDisplayVersion IsUpgradingOrganization
------------------- -----------------------
0.10 (14.16.190.8)                    False
How-To's Office 365

Checking for administrative permissions in PowerShell

Some PowerShell cmdlets require you to have administrative permissions to run them. If you’re creating a script and you’re using such a cmdlet (e.g. writing a file to the root), it would be nice to check up front if the user who is running the script has the required permissions. After all, what good is it to run the script anyway and throw an error?

Fortunately, there’s an easy way in PowerShell to do this. Add the following code to your script and that’s it. It’s a simple if-statement that will stop the script if you don’t have the required permissions. If you do have administrative permissions, nothing happens and the script will continue processing.

If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] “Administrator”))
{
    Write-Warning “You do not have sufficient permissions to run this script!`nPlease re-run this script as an Administrator!”
    Break
}

What happens is that we’re querying the current identity (user who is running the script) and then check whether or not the identity is part of the Built-in Role “Administrator”.

Have fun!

Cheers,

Michael

P.S.: Thanks to Microsoft’s Scripting Guy “Ed Wilson”. Check out his blog: http://blogs.technet.com/b/heyscriptingguy/

How-To's PowerShell

Get a list of installed applications using PowerShell

I was recently at a customer who needed to  get a report of software that was running on each computer. Since they did not have (or at least not fully deployed) a solution that could do that for them (e.g. System Center Configuration Manager), I  proposed to write a PowerShell script which would remotely check a computer using WMI.

Usage

The script accepts a single parameter to indicate the computer you want to get a list of installed applications from:

Get-InstalledApplications –Computer <computername>

The output can be formatted in different ways and even be exported to a file or printed on screen:

Get-InstalledApplications –Computer <computername> | Out-File <file>
or
Get-InstalledApplications -Computer <computername> | Out-GridView

The script

Just copy-paste the code below and save it as a .PS1 file. You can also add the script to your profile so that the function is loaded whenever you open PowerShell.

<#
.Synopsis
   Get a list of the installed applications on a (remote) computer.
.DESCRIPTION
Using WMI (Win32_Product), this script will query a (remote) computer for all installed applications and output the results.
   If required, these results can be exported or printed on screen.
   Please keep in mind that you need to have access to the (remote) computer’s WMI classes.
.EXAMPLE
   To simply list the installed applications, use the script as follows:
   
   Get-InstalledApplications -computer <computername>

.EXAMPLE
   If required, the output of the script can be modified. For instance, viewing the results on screen:
   
   Get-InstalledApplications -computer <computername> | Out-GridView
#>
function Get-InstalledApplications
{
   [CmdletBinding()]
   [OutputType([int])]
   Param
   (
      # defines what computer you want to see the inventory for
      [Parameter(Mandatory=$true,
      ValueFromPipelineByPropertyName=$true,
      Position=0)]
      $computer
   )

   Begin
   {
   }

   Process
   {
      $win32_product = @(get-wmiobject -class ‘Win32_Product’ -computer $computer)

      foreach ($app in $win32_product){
         $applications = New-Object PSObject -Property @{
         Name = $app.Name
         Version = $app.Version
         }

         Write-Output $applications | Select-Object Name,Version
      }
   }

   End
   {
   }
}
How-To's PowerShell

Working with SIDs in PowerShell

Recently, I was creating a PowerShell script in which it turned out that I needed to use SIDs to uniquely identify an object. There might be other ways to uniquely identify an object/account but the SID just seemed easiest.

One of the things I wanted to achieve is to know what object belonged to a specific SID and the other way around. Since I didn’t know if the SID belonged to a user or to a group, I couldn’t rely on the Get-ADUser cmdlet and filter based on the SID:

Get-ADUser –Filter {SID –eq <sid>}

If the SID would belong to a group, the cmdlet above wouldn’t return anything. I could use an if-else statement, but that still would not guarantee a correct result. Furthermore, every time I fire the script I risk that the script has to go through multiple loops which would probably negatively influence the script’s performance.

Luckily, PowerShell has some built-in features that allow you to “convert” an SID into an account (or the other way around). Think about it for a minute: since you already have the SID, you know what account it belongs to. You just need to go and fetch it. There’s no need to loop through all objects and see if a match can be found…

How does it work then? First, we need to create a new object either from the SID class or from the NTAccount class. Afterwards, we fetch the account name where the SID belongs to using the Translate method:

$object = New-Object System.Security.Principal.SecurityIdentifier (“S-1-5-21-1464570058-3711975594-539085127-1210”)
$result = $object.Translate([System.Security.Principal.NTAccount])
$result.Value

This is how it looks like if we run it from PowerShell:image

We can also make it work the other way around (from account name to SID):

$object = New-Object System.Security.Principal.NTAccount(“exblog”,”mvanhorenbeeck”)
$result = $object.Translate([System.Security.Principal.SecurityIdentifier])
$result.Value

image

Note: this approach unfortunately does not work for computer accounts. It can only be used for users or groups.

Blog

Configuring Windows 8 Active Directory Domain Services (ADDS)

Hi there!

As you might know, Windows 8 will bring us tons of new features and improvements, some of which have been long awaited. Over the upcoming weeks, I’ll try to produce some blog posts about these changes and improvements with regards to Active Directory.

Note: the information below is coming from an early version of Windows 8 (developer preview) and there might be small (or bigger) changes in the final version of the product.

Goodbye ‘dcpromo’…

In this first article, I wanted to talk about the configuration of Active Directory. Ever since AD was introduced, IT Pro’s were drilled to use the “dcpromo” command line tool to create a new DC (whether this was to add or remove a DC).

Well, the “era” of this command seems to come to an end with Windows 8 (at least according to what I’ve noticed so far) :

image

As we will see later, and alternative to the tool is now provided by PowerShell.

Configuring ADDS

Entirely according to what I’ve expected, ADDS can be configured from within the redesigned server manager. As soon as you’ve added the ADDS-role, a new option becomes available:

image

image

ADDS Configuration Wizard

Clicking “Promote this server to a domain controller”, will launch the Active Directory Domain Services Configuration Wizard (formerly known as “dcpromo”).

In this scenario, I’ll be adding a domain controller to an existing domain.

On the first page of the wizard, choose your deployment type and enter the necessary details (no surprises here):

image

Select the options for your (new) Domain Controller and choose a Recovery Mode password (don’t loose it!):

image

The setup will now ask to create a DNS delegation. Again: choose the appropriate settings and click Next:

image

Choose where to store AD-related files:

image

The next page contains a nice ‘surprise’: as is the case with Exchange 2010, the wizard allows you to copy-paste the PowerShell-code it is using to execute the task with the selected options. This allows you to easily create your own script(s) from it:

image

image

As you can see, the Install-ADDSDomainController cmdlet is used. This cmdlet is part of the ADDS Deployment Module for PowerShell which has been introduced in Windows Server 8. More information about these cmdlets can be found in one of my previous articles.

Now that we’ve completed the wizard, it will start configuring ADDS. But before doing so, the wizard will run a quick check to see if all prerequisites have been met:

image

You have the option to automatically reboot the server after completion (as was the case with the ‘old’ dcpromo.exe)

image

A final word

In my opinion, these changes – although they might seem small at first – can (and probably will) have an impact on how we deploy domain controllers. I remember that automating the installation (promotion) of a DC could be a real pain in the butt. However, thanks to the new deployment cmdlets and a easy-to-use wizard which is more complete than before, deploying a new or additional DC’s will become a piece of cake.

Does this mean that you should be deploying DC’s just because you can? Of course not. Mind that the ease of deployment might open up some doors to advanced automated deployment in a private cloud, yet deploying a Domain Controller should always be well overthought and –considered.

Until later!

Michael

Blog

Windows 8 Active Directory: New Deployment PowerShell Cmdlets

In my previous blog post, I talked about some of the new cmdlets that were introduced in Windows Server 8 for managing Active Directory. Today, we’ll focus on cmdlets that were added for deploying and configuring Active Directory.

Previously, if you wanted to configure AD DS, you had to use the DCPROMO.exe utility. However, in Windows Server 8 this tool has been deprecated and replaced by a brand new cmdlet: Install-ADDSDomainController.

The cmdlets for deploying ADDS have been grouped into a separate module: ADDSDeployment. As a result, you can run the following command to retrieve a list of all available cmdlets within the module:

Get-Command –Module ADDSDeployment

Get-ActiveDirectoryDomainNames                                                
Get-ActiveDirectorySiteNames                                                  
Invoke-ADDSCanContactOtherDCsinDomain                                         
Invoke-ADDSDoesDCHostOperationMasterRole                                      
Invoke-ADDSDoesDNSDelegationForThisMachineExistInParentZone                   
Invoke-ADDSDoesDomainNamingContextExist                                       
Invoke-ADDSGetAllowedRodcReplicationAccounts                                  
Invoke-ADDSGetApplicationPartitionsInForest                                   
Invoke-ADDSGetDatabaseFacts                                                   
Invoke-ADDSGetDefaultDNSOption                                                
Invoke-ADDSGetDefaultSiteName                                                 
Invoke-ADDSGetDeniedRodcReplicationAccounts                                   
Invoke-ADDSGetDnsDelegationOptions                                            
Invoke-ADDSGetDomainControllersInDomain                                       
Invoke-ADDSGetExistingDCAccountInfo                                           
Invoke-ADDSGetForestFunctionalLevel                                           
Invoke-ADDSGetGeneratedNetbiosName                                            
Invoke-ADDSGetNDNCListWithNoOtherReplicas                                     
Invoke-ADDSGetSuitableHelperDomainController                                  
Invoke-ADDSIsDc                                                               
Invoke-ADDSIsRodc                                                             
Invoke-ExpandEnvironmentVariables                                             
Restart-DeploymentTarget                                                      
Test-VerifyADPrepCredential                                                   
Test-VerifyAppPartitionRemoval                                                
Test-VerifyAvailableWinDirSpace                                               
Test-VerifyCertServiceExists                                                  
Test-VerifyChild                                                              
Test-VerifyComputerName                                                       
Test-VerifyComputerWasRenamedAndNeedsReboot                                   
Test-VerifyCurrentUserIsAdministrator                                         
Test-VerifyDCServiceAvailableForDemotion                                      
Test-VerifyDemote                                                             
Test-VerifyDnsConfigOptions                                                   
Test-VerifyDnsDelegationRemoval                                               
Test-VerifyDnsRegistration                                                    
Test-VerifyDomainUpgradeStatus                                                
Test-VerifyForestName                                                         
Test-VerifyForestUpgradeStatus                                                
Test-VerifyFsmoForceRemoval                                                   
Test-VerifyInfrastructureMasterOnline                                         
Test-VerifyIsComputerNameValid                                                
Test-VerifyMachineAdminPassword                                               
Test-VerifyNamingMasterOnline                                                 
Test-VerifyNetBiosName                                                        
Test-VerifyNotInSafeBootMode                                                  
Test-VerifyNtfs5DriveAvailable                                                
Test-VerifyPaths                                                              
Test-VerifyReplica                                                            
Test-VerifyReplicateFromMedia                                                 
Test-VerifyReplicationPartner                                                 
Test-VerifyRequiredPortsAreAvailable                                          
Test-VerifyRODCUpgradeStatus                                                  
Test-VerifySafeModePassword                                                   
Test-VerifySchemaMasterOnline                                                 
Test-VerifySelectedDcAccount                                                  
Test-VerifySiteSelection                                                      
Test-VerifySupportedPlatform                                                  
Test-VerifyTcpIPIsInstalledAndFunctioning                                     
Test-VerifyTree                                                               
Test-VerifyUserCredentialPermissions                                          
Test-VerifyUserCredentials                                                    
Test-VerifyValidRoleChangeState                                               
Add-ADDSReadOnlyDomainControllerAccount                                       
Install-ADDSDomain                                                            
Install-ADDSDomainController                                                  
Install-ADDSForest                                                            
Test-ADDSDomainControllerInstallation                                         
Test-ADDSDomainControllerUninstallation                                       
Test-ADDSDomainInstallation                                                   
Test-ADDSForestInstallation                                                   
Test-ADDSReadOnlyDomainControllerAccountCreation                              
Uninstall-ADDSDomainController                                                

Together with new deployment cmdlets, you now have also a bunch of test-cmdlets which can verify your installation and prove useful during troubleshooting.

We’re facing some exiting times as these new cmdlets will allow you to create more comprehensive scripts. Not only for AD Management, but also for deployment and testing!

Until later!

Blog

Windows 8 Active Directory: New PowerShell Cmdlets

Windows 8 Server will bring a whole lot of changes compared to it’s predecessor: Windows 2008 R2. There has already been a lot of fuzz about these changes, and today I’d like to take a moment and take a look at what new cmdlets we’ve been given to manage Active Directory.

As you all know, Server 2008 R2 gave us the ability to natively manage Active Directory from PowerShell through the AD Module for PowerShell. Unfortunately, not everything could be managed. Although third-party tools (like Quest’s AD cmdlets) made up for it, I always missed the “native” support.

With Windows 8, Microsoft has added quite some new cmdlets to support Active Directory (58 to be exactly), which brings the total amount of cmdlets in the AD Module to 134! Please not that I got this number from the Developer preview and it’s always possible that this amount changes in the RTM-version.

A lot of the new cmdlets fit the gap with before (e.g. AD Replication), others are related to new features as the new claims-based “Dynamic Access Control”.

The following list shows all the cmdlets that have been added:

Add-ADCentralAccessPolicyMember
Add-ADResourcePropertyListMember
Clear-ADClaimTransformLink
Get-ADCentralAccessPolicy                                                     
Get-ADCentralAccessRule                                                       
Get-ADClaimTransformPolicy                                                    
Get-ADClaimType   
Get-ADDCCloningExcludedApplicationList  
Get-ADReplicationAttributeMetadata                                            
Get-ADReplicationConnection                                                   
Get-ADReplicationFailure                                                      
Get-ADReplicationPartnerMetadata                                              
Get-ADReplicationQueueOperation                                               
Get-ADReplicationSite                                                         
Get-ADReplicationSiteLink                                                     
Get-ADReplicationSiteLinkBridge                                               
Get-ADReplicationSubnet                                                       
Get-ADReplicationUpToDatenessVectorTable                                      
Get-ADResourceProperty                                                        
Get-ADResourcePropertyList                                                    
Get-ADResourcePropertyValueType
Get-ADTrust 
New-ADCentralAccessPolicy                                                     
New-ADCentralAccessRule                                                       
New-ADClaimTransformPolicy                                                    
New-ADClaimType            
New-ADReplicationSite                                                         
New-ADReplicationSiteLink                                                     
New-ADReplicationSiteLinkBridge                                               
New-ADReplicationSubnet                                                       
New-ADResourceProperty                                                        
New-ADResourcePropertyList 
Remove-ADCentralAccessPolicy                                                  
Remove-ADCentralAccessPolicyMember                                            
Remove-ADCentralAccessRule                                                    
Remove-ADClaimTransformPolicy                                                 
Remove-ADClaimType          
Remove-ADReplicationSite                                                      
Remove-ADReplicationSiteLink                                                  
Remove-ADReplicationSiteLinkBridge                                            
Remove-ADReplicationSubnet                                                    
Remove-ADResourceProperty                                                     
Remove-ADResourcePropertyList                                                 
Remove-ADResourcePropertyListMember  
Set-ADCentralAccessPolicy                                                     
Set-ADCentralAccessRule                                                       
Set-ADClaimTransformLink                                                      
Set-ADClaimTransformPolicy                                                    
Set-ADClaimType        
Set-ADReplicationConnection                                                   
Set-ADReplicationSite                                                         
Set-ADReplicationSiteLink                                                     
Set-ADReplicationSiteLinkBridge                                               
Set-ADReplicationSubnet                                                       
Set-ADResourceProperty                                                        
Set-ADResourcePropertyList
Sync-ADObject                                                                 
Test-ADServiceAccount  

Note: if you are interested in getting the full list of cmdlets, try running the following cmdlet:

Get-Command –Module ActiveDirectory

To view the total amount of cmdlets, you could easily do the following:

$commands = Get-Command –Module ActiveDirectory
$commands.count

Until later,

Michael

Blog