Tag Archives: WMI

Active Directory Friday: Use MSAD_ReplNeighbor WMI class to replicate Active Directory

This article will provide details of initiating replication of using WMI in PowerShell. There are a lot of possible methods of starting replication such as using the ‘Active Directory Sites and Services’ console, using the Active Directory PowerShell module and the Sync-ADObject cmdlet.

We will use the MSAD_ReplNeighbor WMI Class for this purpose and specifically the SyncNamingContext method to initiate replication. This class is available in the root\MicrosoftActiveDirectory path on your domain controllers. The commands in this article should be executed on a domain controller. I have made the choice the use the Get-WmiObject in this article as the SyncNamingContext method is not available when using the Get-CimInstance cmdlet, aside from that method all commands can be executed using the Get-CimInstance

In the first code example I will access the MSAD_ReplNeighbor class and retrieve all information. In this article I will use a technique called splatting to input the parameters into the cmdlet:

1
2
3
4
5
$WmiSplat = @{
    Class = 'MSAD_ReplNeighbor'
    Namespace = 'root\MicrosoftActiveDirectory'
}
Get-WmiObject @WmiSplat | Get-Member

The output from this command will display all the available properties and methods, including the SyncNamingContext method that we will use in this article. To view the available partitions for replication, we can use the Select-Object cmdlet to only select the Unique NamingContextDN properties of the returned objects:

1
2
3
4
5
$WmiSplat = @{
    Class = 'MSAD_ReplNeighbor'
    Namespace = 'root\MicrosoftActiveDirectory'
}
Get-WmiObject @WmiSplat | Select-Object -Property NamingContextDN -Unique

Replicate-UniqueNamingDN

Based on this output we determine that the ‘DC=jaapbrasser,DC=com’ partition is the partition we are interested in. In the following code we will filter out only that partion and display a number of selected properties:

1
2
3
4
5
6
$WmiSplat = @{
    Class = 'MSAD_ReplNeighbor'
    Namespace = 'root\MicrosoftActiveDirectory'
    Filter = "NamingContextDN = 'DC=jaapbrasser,DC=com'"
}
Get-WmiObject @WmiSplat | Select-Object -Property SourceDsaCN,SourceDsaSite,TimeOfLastSyncSuccess,Replicaflags

Replicate-ViewReplication

The first thing that you’ll notice is that the two properties Replicaflags and TimeOfLastSyncSuccess are hard to read, in the following two examples two different approaches are shown to properly convert the TimeOfLastSyncSuccess property to a more human readable output:

1
2
3
4
5
6
7
8
9
10
$WmiSplat = @{
    Class = 'MSAD_ReplNeighbor'
    Namespace = 'root\MicrosoftActiveDirectory'
    Filter = "NamingContextDN = 'DC=jaapbrasser,DC=com'"
}
$DateTimeOfLastSyncSuccess = @{
    Name = 'DateTimeOfLastSyncSuccess'
    Expression = {[Management.ManagementDateTimeConverter]::ToDateTime($_.TimeOfLastSyncSuccess)}
}
Get-WmiObject @WmiSplat | Select-Object -Property SourceDsaCN,SourceDsaSite,$DateTimeOfLastSyncSuccess,Replicaflags

Alternatively we can use the Get-CimInstance cmdlet which already provides the converted object:

1
2
3
4
5
6
$CimSplat = @{
    Class = 'MSAD_ReplNeighbor'
    Namespace = 'root\MicrosoftActiveDirectory'
    Filter = "NamingContextDN = 'DC=jaapbrasser,DC=com'"
}
Get-CimInstance @CimSplat | Select-Object -Property SourceDsaCN,SourceDsaSite,TimeOfLastSyncSuccess,Replicaflags

Replicate-CimInstance

In order to be able to convert the Replicaflags attribute the value in the property should be converted using the table found in MSAD_ReplNeighbor class article on MSDN. Here is a portion of the the table available on MSDN:

Value

DS_REPL_NBR_WRITEABLE
16 (0x10)

DS_REPL_NBR_SYNC_ON_STARTUP
32 (0x20)

DS_REPL_NBR_DO_SCHEDULED_SYNCS
64 (0x40)

DS_REPL_NBR_USE_ASYNC_INTERSITE_TRANSPORT
128 (0x80)

DS_REPL_NBR_TWO_WAY_SYNC
512 (0x200)

DS_REPL_NBR_RETURN_OBJECT_PARENTS
2048 (0x800)

DS_REPL_NBR_FULL_SYNC_IN_PROGRESS
65536 (0x10000)

DS_REPL_NBR_FULL_SYNC_NEXT_PACKET
131072 (0x20000)

DS_REPL_NBR_NEVER_SYNCED
2097152 (0x200000)

DS_REPL_NBR_PREEMPTED
16777216 (0x1000000)

DS_REPL_NBR_IGNORE_CHANGE_NOTIFICATIONS
67108864 (0x4000000)

DS_REPL_NBR_DISABLE_SCHEDULED_SYNC
134217728 (0x8000000)

DS_REPL_NBR_COMPRESS_CHANGES
268435456 (0x10000000)

DS_REPL_NBR_NO_CHANGE_NOTIFICATIONS
536870912 (0x20000000)

DS_REPL_NBR_PARTIAL_ATTRIBUTE_SET
1073741824 (0x40000000)

Using the information in this table in combination with the Switch statement the output can be converted in a more human readable format, listing all the flags in text instead of a single integer. In the next example I have also updated the Filter to automatically fill in the current domain name by using the [adsi] type accelerator to select the distinguishedname of the default naming context:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$WmiSplat = @{
    Class = 'MSAD_ReplNeighbor'
    Namespace = 'root\MicrosoftActiveDirectory'
    Filter = "NamingContextDN = '$(-join ([adsi]'').distinguishedname)'"
}
$DateTimeOfLastSyncSuccess = @{
    Name = 'DateTimeOfLastSyncSuccess'
    Expression = {[Management.ManagementDateTimeConverter]::ToDateTime($_.TimeOfLastSyncSuccess)}
}
$ReadableReplicaFlags = @{
    Name = 'ReadableReplicaFlags'
    Expression = {
        Switch ($_.ReplicaFlags) {
            {$_ -bor 0x10} {'DS_REPL_NBR_WRITEABLE'}
            {$_ -bor 0x20} {'DS_REPL_NBR_SYNC_ON_STARTUP'}
            {$_ -bor 0x40} {'DS_REPL_NBR_DO_SCHEDULED_SYNCS'}
            {$_ -bor 0x80} {'DS_REPL_NBR_USE_ASYNC_INTERSITE_TRANSPORT'}
            {$_ -bor 0x200} {'DS_REPL_NBR_TWO_WAY_SYNC'}
            {$_ -bor 0x800} {'DS_REPL_NBR_RETURN_OBJECT_PARENTS'}
            {$_ -bor 0x10000} {'DS_REPL_NBR_FULL_SYNC_IN_PROGRESS'}
            {$_ -bor 0x20000} {'DS_REPL_NBR_FULL_SYNC_NEXT_PACKET'}
            {$_ -bor 0x200000} {'DS_REPL_NBR_NEVER_SYNCED'}
            {$_ -bor 0x1000000} {'DS_REPL_NBR_PREEMPTED'}
            {$_ -bor 0x4000000} {'DS_REPL_NBR_IGNORE_CHANGE_NOTIFICATIONS'}
            {$_ -bor 0x8000000} {'DS_REPL_NBR_DISABLE_SCHEDULED_SYNC'}
            {$_ -bor 0x10000000} {'DS_REPL_NBR_COMPRESS_CHANGES'}
            {$_ -bor 0x20000000} {'DS_REPL_NBR_NO_CHANGE_NOTIFICATIONS'}
            {$_ -bor 0x40000000} {'DS_REPL_NBR_PARTIAL_ATTRIBUTE_SET'}
        }
    }
}
Get-WmiObject @WmiSplat | Select-Object -Property SourceDsaCN,SourceDsaSite,$DateTimeOfLastSyncSuccess,$ReadableReplicaFlags

Replicate-Formatted

By creating both the $DateTimeOfLastSyncSuccess and $ReadableReplicaFlags hashtables, the content can now be displayed in a human readable format, which should make it easier to determine how replication is progressing or where it would be interesting to attempt to initiate replication.

The following example will start replication of the domain partition with all site links of the current server. The ClassName and Filter parameter have been replaced by the Query parameter to illustrate a different approach of querying for this information.

1
2
3
4
5
6
7
8
$WmiSplat = @{
    Namespace = 'root\MicrosoftActiveDirectory'
    Query = "Select * From MSAD_ReplNeighbor Where NamingContextDN = '$(-join ([adsi]'').distinguishedname)'"
}
Get-WmiObject @WmiSplat | ForEach-Object {
    Write-Output "Replicate domain partition: $($_.Domain) from DC: $($_.SourceDsaCN) in the $($_.SourceDsaSite) site"
    $_.SyncNamingContext()
}

Replicate-Replication

This will replicate the domain partition with the defined site links. The Write-Output cmdlet will show which DC and which site replication has been started with. The SyncNamingContext method does accept a single argument as well, an integer that contains the parameters for this method.

For a complete overview of the available parameters please refer to this table:

Parameter Value
DS_REPSYNC_ASYNCHRONOUS_OPERATION 0x1
DS_REPSYNC_WRITEABLE 0x2
DS_REPSYNC_PERIODIC 0x4
DS_REPSYNC_INTERSITE_MESSAGING 0x8
DS_REPSYNC_ALL_SOURCES 0x10
DS_REPSYNC_FULL 0x20
DS_REPSYNC_URGENT 0x40
DS_REPSYNC_NO_DISCARD 0x80
DS_REPSYNC_FORCE 0x100
DS_REPSYNC_ADD_REFERENCE 0x200

Using the examples in this article you can now verify when replication last occurred and replicate a Active Directory partition between two or multiple sites. If you have any questions or feedback on this article feel free to use the comments section and for more information on this MSAD_ReplNeighbor WMI class have a look at the following resources:

MSAD_ReplNeighbor WMI class
MSAD_ReplNeighbor class
SyncNamingContext method of the MSAD_ReplNeighbor class

Share

QuickTip: Use WMI to determine remote users accessing files and shares

A question popped up on the PowerShell.com forums, asking if it was possible to view a list of users accessing network shares on a system. It turns out this is a relatively easy task using WMI

Get-WmiObject -Class Win32_ServerConnection -ComputerName server01

Now this does output a large amount of data, so I would recommend filtering some of the more useful properties for example:

Get-WmiObject -Class Win32_ServerConnection -ComputerName server01 |
Select-Object -Property ComputerName,ConnectionID,UserName,ShareName

Of course it is also possible to query for this information using the newer Get-CimInstance cmdlet:

Get-CimInstance -Class Win32_ServerConnection -ComputerName server01

There you have it, accessing the full list of users from a local or remote system that are accessing shared folders on the system is quite easily done when using PowerShell.

Share

New article on PowerShell Magazine: Select non-administrative shared folders using Win32_Share WMI class

Today’s tip is on how to use the Type property of the Win32_Share class to select only non-administrative shares from a local or remote system. This class can be used in combination with the Get-WmiObject or Get-CimInstance cmdlets to gather this data. The examples in this articles show how this can be used against a remote system. The article is available on PowerShell Magazine:

http://www.powershellmagazine.com/2014/07/24/pstip-select-non-administrative-shared-folders-using-win32_share-wmi-class/

Share

QuickTip: Using Win32_Share to only select non-default shares

The Win32_Share class can be used to remotely or locally gather a listed of shared folders and their properties. Since every Windows system by default has a number of standard shared folder it can be interesting to only select the non-default shares. The following line of code allows you to do that:

Get-WmiObject Win32_Share | Where-Object {(@('Remote Admin','Default share','Remote IPC') -notcontains $_.Description)}

Note that this only works for systems with English localization options. For other languages the names in the array will have to be changed to match to localized names.

Share