PowerShell GUIs - Active Directory, Directory Object Picker?
So getting the OpenFileDialog box is amazingly easy in PowerShell so I assumed the DirectoryObjectPicker might also be as easy. However, I cant' find any reference for using PowerShell with the DirectoryObjectPicker. Can it be done?
Ultimately, what I'm trying to do is: at the click of a button, enumerate our AD hierarchy so the user can select the OU level they want to filter a search on. -- If that added information helps...
Edit:
PowerShell OpenFileDialog:
http://blogs.technet.com/b/heyscriptingguy/archive/2009/09/01/hey-scripting-guy-september-1.aspx
C++ DirectoryObjectPicker:
http://msdn.microsoft.com/en-us/library/ms675899(v=vs.85).aspx
I haven't had much free time to work on this, but I'm glad you found a workaround. Here's the beginnings of a script named Show-DsObjectPicker.ps1 that displays a down-level DsObjectPicker window for either the current host or the host passed to the -computername
parameter. It demonstrates several key bits of PowerShell functionality and lots of silly workarounds for PowerShell behavior that's either unforgiving or something I don't quite grok. ;-) This should really go into an snap-in (maybe PSCX) as a full-featured
cmdlet written in C#.
# Show-DsObjectPicker.ps1
param(
[string]
$ComputerName
add-type -typedefinition @"
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
public enum DsScope : uint
DSOP_SCOPE_TYPE_TARGET_COMPUTER = 0x00000001,
DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN = 0x00000002,
DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN = 0x00000004,
DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN = 0x00000008,
DSOP_SCOPE_TYPE_GLOBAL_CATALOG = 0x00000010,
DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN = 0x00000020,
DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN = 0x00000040,
DSOP_SCOPE_TYPE_WORKGROUP = 0x00000080,
DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE = 0x00000100,
DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE = 0x00000200
public enum DsScopeInitInfo : uint
DSOP_SCOPE_FLAG_STARTING_SCOPE = 0x00000001,
DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT = 0x00000002,
DSOP_SCOPE_FLAG_WANT_PROVIDER_LDAP = 0x00000004,
DSOP_SCOPE_FLAG_WANT_PROVIDER_GC = 0x00000008,
DSOP_SCOPE_FLAG_WANT_SID_PATH = 0x00000010,
DSOP_SCOPE_FLAG_WANT_DOWNLEVEL_BUILTIN_PATH = 0x00000020,
DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS = 0x00000040,
DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS = 0x00000080,
DSOP_SCOPE_FLAG_DEFAULT_FILTER_COMPUTERS = 0x00000100,
DSOP_SCOPE_FLAG_DEFAULT_FILTER_CONTACTS = 0x00000200,
DSOP_SCOPE_FLAG_DEFAULT_FILTER_SERVICE_ACCOUNTS = 0x00000400
public enum DsFilter : uint
DSOP_FILTER_INCLUDE_ADVANCED_VIEW = 0x00000001,
DSOP_FILTER_USERS = 0x00000002,
DSOP_FILTER_BUILTIN_GROUPS = 0x00000004,
DSOP_FILTER_WELL_KNOWN_PRINCIPALS = 0x00000008,
DSOP_FILTER_UNIVERSAL_GROUPS_DL = 0x00000010,
DSOP_FILTER_UNIVERSAL_GROUPS_SE = 0x00000020,
DSOP_FILTER_GLOBAL_GROUPS_DL = 0x00000040,
DSOP_FILTER_GLOBAL_GROUPS_SE = 0x00000080,
DSOP_FILTER_DOMAIN_LOCAL_GROUPS_DL = 0x00000100,
DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE = 0x00000200,
DSOP_FILTER_CONTACTS = 0x00000400,
DSOP_FILTER_COMPUTERS = 0x00000800,
DSOP_FILTER_SERVICE_ACCOUNTS = 0x00001000
public enum DsDownlevelFilter : uint
DSOP_DOWNLEVEL_FILTER_USERS = 0x80000001,
DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS = 0x80000002,
DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS = 0x80000004,
DSOP_DOWNLEVEL_FILTER_COMPUTERS = 0x80000008,
DSOP_DOWNLEVEL_FILTER_WORLD = 0x80000010,
DSOP_DOWNLEVEL_FILTER_AUTHENTICATED_USER = 0x80000020,
DSOP_DOWNLEVEL_FILTER_ANONYMOUS = 0x80000040,
DSOP_DOWNLEVEL_FILTER_BATCH = 0x80000080,
DSOP_DOWNLEVEL_FILTER_CREATOR_OWNER = 0x80000100,
DSOP_DOWNLEVEL_FILTER_CREATOR_GROUP = 0x80000200,
DSOP_DOWNLEVEL_FILTER_DIALUP = 0x80000400,
DSOP_DOWNLEVEL_FILTER_INTERACTIVE = 0x80000800,
DSOP_DOWNLEVEL_FILTER_NETWORK = 0x80001000,
DSOP_DOWNLEVEL_FILTER_SERVICE = 0x80002000,
DSOP_DOWNLEVEL_FILTER_SYSTEM = 0x80004000,
DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS = 0x80008000,
DSOP_DOWNLEVEL_FILTER_TERMINAL_SERVER = 0x80010000,
DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS = 0x80020000,
DSOP_DOWNLEVEL_FILTER_LOCAL_SERVICE = 0x80040000,
DSOP_DOWNLEVEL_FILTER_NETWORK_SERVICE = 0x80080000,
DSOP_DOWNLEVEL_FILTER_REMOTE_LOGON = 0x80100000,
DSOP_DOWNLEVEL_FILTER_INTERNET_USER = 0x80200000,
DSOP_DOWNLEVEL_FILTER_OWNER_RIGHTS = 0x80400000,
DSOP_DOWNLEVEL_FILTER_SERVICES = 0x80800000,
DSOP_DOWNLEVEL_FILTER_LOCAL_LOGON = 0x81000000,
DSOP_DOWNLEVEL_FILTER_THIS_ORG_CERT = 0x82000000,
DSOP_DOWNLEVEL_FILTER_IIS_APP_POOL = 0x84000000
public enum DsInitInfo : uint
DSOP_FLAG_MULTISELECT = 0x00000001,
DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK = 0x00000002
[StructLayout(LayoutKind.Sequential)]
public struct DSOP_UPLEVEL_FILTER_FLAGS
//public DsFilter flBothModes;
//public DsFilter flMixedModeOnly;
//public DsFilter flNativeModeOnly;
public uint flBothModes;
public uint flMixedModeOnly;
public uint flNativeModeOnly;
[StructLayout(LayoutKind.Sequential)]
public struct DSOP_FILTER_FLAGS
public DSOP_UPLEVEL_FILTER_FLAGS Uplevel;
//public DsDownlevelFilter flDownlevel;
public uint flDownlevel;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DSOP_SCOPE_INIT_INFO
public uint cbSize;
//public DsScope flType;
public uint flType;
//public DsScopeInitInfo flScope;
public uint flScope;
public DSOP_FILTER_FLAGS FilterFlags;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzDcName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzADsPath;
public uint hr;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DSOP_INIT_INFO
public uint cbSize;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzTargetComputer;
public uint cDsScopeInfos;
public IntPtr aDsScopeInfos;
//public DsInitInfo flOptions;
public uint flOptions;
public uint cAttributesToFetch;
public IntPtr apwzAttributeNames;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DS_SELECTION
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzADsPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzClass;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzUPN;
public IntPtr pvarFetchedAttributes;
public uint flScopeType;
[StructLayout(LayoutKind.Sequential)]
public struct DS_SELECTION_LIST
public uint cItems;
public uint cFetchedAttributes;
//public IntPtr aDsSelection;
[Guid("0c87e64e-3b7a-11d2-b9e0-00c04fd8dbf7"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDsObjectPicker
void Initialize(
[In] ref DSOP_INIT_INFO pInitInfo);
void InvokeDialog(
[In] IntPtr hwndParent,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppdoSelections);
[Guid("e2d3ec9b-d041-445a-8f16-4748de8fb1cf"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDsObjectPickerCredentials
void SetCredentials(
[In, MarshalAs(UnmanagedType.LPWStr)] string szUserName,
[In, MarshalAs(UnmanagedType.LPWStr)] string szPassword);
[ComImport, Guid("17d6ccd8-3b7b-11d2-b9e0-00c04fd8dbf7")]
public class __DsObjectPicker
public class DsObjectPicker
private __DsObjectPicker p;
public static string CFSTR_DSOP_DS_SELECTION_LIST = "CFSTR_DSOP_DS_SELECTION_LIST";
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GlobalLock([In] IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint GlobalUnlock([In] IntPtr handle);
[DllImport("ole32.dll")]
public static extern void ReleaseStgMedium([In] ref STGMEDIUM pmedium);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegisterClipboardFormat(string lpszFormat);
public DsObjectPicker()
p = new __DsObjectPicker();
public void Initialize(ref DSOP_INIT_INFO pInitInfo)
IDsObjectPicker i = p as IDsObjectPicker;
i.Initialize(ref pInitInfo);
public DataObject InvokeDialog(IntPtr hwndParent)
object pdoSelections;
IDsObjectPicker i = p as IDsObjectPicker;
i.InvokeDialog(hwndParent, out pdoSelections);
return new DataObject(pdoSelections as IDataObject);
public void SetCredentials(string szUserName, string szPassword)
IDsObjectPickerCredentials i = p as IDsObjectPickerCredentials;
i.SetCredentials(szUserName, szPassword);
public class DataObject
private IDataObject p;
public DataObject(IDataObject i)
p = i;
public void GetData(ref FORMATETC format, out STGMEDIUM medium)
p.GetData(ref format, out medium);
$aDsScopeInfos = @()
$DsScopeInfos = new-object DSOP_SCOPE_INIT_INFO
$DsScopeInfos.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf([DSOP_SCOPE_INIT_INFO])
$DsScopeInfos.flType = [DsScope]::DSOP_SCOPE_TYPE_TARGET_COMPUTER
$DsScopeInfosFilterFlags = new-object DSOP_FILTER_FLAGS
$DsScopeInfosFilterFlags.flDownLevel = [DsDownlevelFilter]::DSOP_DOWNLEVEL_FILTER_USERS
$DsScopeInfos.FilterFlags = $DsScopeInfosFilterFlags
$DsScopeInfos.hr = 0
$aDsScopeInfos += $DsScopeInfos
$aDsScopeInfosPtr =
[System.Runtime.InteropServices.Marshal]::AllocCoTaskMem(
$aDsScopeInfos.Length * [System.Runtime.InteropServices.Marshal]::SizeOf([DSOP_SCOPE_INIT_INFO]))
$aDsScopeInfosPtrTmp = $aDsScopeInfosPtr
foreach ($DsScopeInfo in $aDsScopeInfos)
[System.Runtime.InteropServices.Marshal]::StructureToPtr($DsScopeInfo, $aDsScopeInfosPtrTmp, $false)
$aDsScopeInfosPtrTmp = [IntPtr] ($aDsScopeInfosPtrTmp.ToInt64() +
[System.Runtime.InteropServices.Marshal]::SizeOf([DSOP_SCOPE_INIT_INFO]))
$DsInitInfo = new-object DSOP_INIT_INFO
$DsInitInfo.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf([DSOP_INIT_INFO])
$DsInitInfo.pwzTargetComputer = $ComputerName
$DsInitInfo.cDsScopeInfos = $aDsScopeInfos.Length
$DsInitInfo.aDsScopeInfos = $aDsScopeInfosPtr
$DsInitInfo.flOptions = [DsInitInfo]::DSOP_FLAG_MULTISELECT
$DsObjectPicker = new-object DsObjectPicker
$DsObjectPicker.Initialize([ref] $DsInitInfo)
$DataObject = $DsObjectPicker.InvokeDialog((get-process -id $pid).MainWindowHandle)
if (-not ($DataObject -eq $null))
$medium = new-object System.Runtime.InteropServices.ComTypes.STGMEDIUM
$format = new-object System.Runtime.InteropServices.ComTypes.FORMATETC
$format.cfFormat =
[Int16]::Parse([DsObjectPicker]::RegisterClipboardFormat([DsObjectPicker]::CFSTR_DSOP_DS_SELECTION_LIST).ToString("X4"),
[System.Globalization.NumberStyles]::HexNumber)
$format.dwAspect = [System.Runtime.InteropServices.ComTypes.DVASPECT]::DVASPECT_CONTENT
$format.lindex = -1
$format.tymed = [System.Runtime.InteropServices.ComTypes.TYMED]::TYMED_HGLOBAL
$DataObject.GetData([ref] $format, [ref] $medium)
try
$DsSelectionListPtr = [DsObjectPicker]::GlobalLock($medium.unionmember)
try
$DsSelectionList =
[DS_SELECTION_LIST] [System.Runtime.InteropServices.Marshal]::PtrToStructure($DsSelectionListPtr, [DS_SELECTION_LIST])
$DsSelectionPtr = [IntPtr] ($DsSelectionListPtr.ToInt64() + [System.Runtime.InteropServices.Marshal]::SizeOf([DS_SELECTION_LIST]))
for ($i = 0; $i -lt $DsSelectionList.cItems; $i++)
$DsSelection = new-object DS_SELECTION
$DsSelection = [DS_SELECTION] [System.Runtime.InteropServices.Marshal]::PtrToStructure($DsSelectionPtr, [DS_SELECTION])
new-object System.DirectoryServices.DirectoryEntry($DsSelection.pwzADsPath)
$DsSelectionPtr = [IntPtr] ($DsSelectionPtr.ToInt64() + [System.Runtime.InteropServices.Marshal]::SizeOf([DS_SELECTION]))
finally
[DsObjectPicker]::GlobalUnlock($medium.unionmember) | out-null
finally
[DsObjectPicker]::ReleaseStgMedium([ref] $medium)
[System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($aDsScopeInfosPtr)
Trev
Similar Messages
-
[Forum FAQ] Using PowerShell to assign permissions on Active Directory objects
As we all know, the
ActiveDirectoryAccessRule class is used to represent an access control entry (ACE) in the discretionary access control list (DACL) of an Active Directory Domain Services object.
To set the permissions on Active Directory objects, the relevant classes and their enumerations are listed as below:
System.DirectoryServices.ActiveDirectoryAccessRule class:
http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectoryaccessrule(v=vs.110).aspx
System.DirectoryServices.ActiveDirectoryRights
class:
http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectoryrights(v=vs.110).aspx
System.Security.AccessControl.AccessControlType class:
http://msdn.microsoft.com/en-us/library/w4ds5h86(v=vs.110).aspx
System.DirectoryServices.ActiveDirectorySecurityInheritance class:
http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectorysecurityinheritance(v=vs.110).aspx
In this article, we introduce three ways to get and set the ACE on an Active Directory object. In general,
we use Active Directory Service Interfaces (ADSI) or
Active Directory module cmdlets
with the Get-Acl and Set-Acl cmdlets to assign simple permissions on Active Directory objects. In addition, we can use the extended rights and GUID settings to execute
more complex permission settings.
Method 1: Using ADSI
1. Get current permissions of an organization unit (OU)
We can use the PowerShell script below to get current permissions of an organization unit and you just need to define the name of the OU.
$Name = "OU=xxx,DC=com"
$ADObject = [ADSI]"LDAP://$Name"
$aclObject = $ADObject.psbase.ObjectSecurity
$aclList = $aclObject.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier])
$output=@()
foreach($acl in $aclList)
$objSID = New-Object System.Security.Principal.SecurityIdentifier($acl.IdentityReference)
$info = @{
'ActiveDirectoryRights' = $acl.ActiveDirectoryRights;
'InheritanceType' = $acl.InheritanceType;
'ObjectType' = $acl.ObjectType;
'InheritedObjectType' = $acl.InheritedObjectType;
'ObjectFlags' = $acl.ObjectFlags;
'AccessControlType' = $acl.AccessControlType;
'IdentityReference' = $acl.IdentityReference;
'NTAccount' = $objSID.Translate( [System.Security.Principal.NTAccount] );
'IsInherited' = $acl.IsInherited;
'InheritanceFlags' = $acl.InheritanceFlags;
'PropagationFlags' = $acl.PropagationFlags;
$obj = New-Object -TypeName PSObject -Property $info
$output+=$obj}
$output
In the figure below, you can see the results of running the script above:
Figure 1.
2. Assign a computer object with Full Control permission on an OU
We can use the script below to delegate Full Control permission to the computer objects within an OU:
$SysManObj = [ADSI]("LDAP://OU=test….,DC=com") #get the OU object
$computer = get-adcomputer "COMPUTERNAME" #get the computer object which will be assigned with Full Control permission within an OU
$sid = [System.Security.Principal.SecurityIdentifier] $computer.SID
$identity = [System.Security.Principal.IdentityReference] $SID
$adRights = [System.DirectoryServices.ActiveDirectoryRights] "GenericAll"
$type = [System.Security.AccessControl.AccessControlType] "Allow"
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All"
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$inheritanceType #set permission
$SysManObj.psbase.ObjectSecurity.AddAccessRule($ACE)
$SysManObj.psbase.commitchanges()
After running the script above, you can check the computer object in Active Directory Users and Computers (ADUC) and it is under the Security tab in OU Properties.
Method 2: Using Active Directory module with the Get-Acl and Set-Acl cmdlets
You can use the script below to get and assign Full Control permission to a computer object on an OU:
$acl = get-acl "ad:OU=xxx,DC=com"
$acl.access #to get access right of the OU
$computer = get-adcomputer "COMPUTERNAME"
$sid = [System.Security.Principal.SecurityIdentifier] $computer.SID
# Create a new access control entry to allow access to the OU
$identity = [System.Security.Principal.IdentityReference] $SID
$adRights = [System.DirectoryServices.ActiveDirectoryRights] "GenericAll"
$type = [System.Security.AccessControl.AccessControlType] "Allow"
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All"
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$inheritanceType
# Add the ACE to the ACL, then set the ACL to save the changes
$acl.AddAccessRule($ace)
Set-acl -aclobject $acl "ad:OU=xxx,DC=com"
Method 3: Using GUID setting
The scripts above can only help us to complete simple tasks, however, we may want to execute more complex permission settings. In this scenario, we can use GUID settings to achieve
that.
The specific ACEs allow an administrator to delegate Active Directory specific rights (i.e. extended rights) or read/write access to a property set (i.e. a named collection of attributes) by
setting ObjectType field in an object specific ACE to the
rightsGuid of the extended right or property set. The delegation can also be created to target child objects of a specific class by setting the
InheritedObjectType field to the schemaIDGuid of the class.
We choose to use this pattern: ActiveDirectoryAccessRule(IdentityReference, ActiveDirectoryRights, AccessControlType, Guid, ActiveDirectorySecurityInheritance, Guid)
You can use the script below to
assign the group object with the permission to change user password on all user objects within an OU.
$acl = get-acl "ad:OU=xxx,DC=com"
$group = Get-ADgroup xxx
$sid = new-object System.Security.Principal.SecurityIdentifier $group.SID
# The following object specific ACE is to grant Group permission to change user password on all user objects under OU
$objectguid = new-object Guid
00299570-246d-11d0-a768-00aa006e0529 # is the rightsGuid for the extended right User-Force-Change-Password (“Reset Password”)
class
$inheritedobjectguid = new-object Guid
bf967aba-0de6-11d0-a285-00aa003049e2 # is the schemaIDGuid for the user
$identity = [System.Security.Principal.IdentityReference] $SID
$adRights = [System.DirectoryServices.ActiveDirectoryRights] "ExtendedRight"
$type = [System.Security.AccessControl.AccessControlType]
"Allow"
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "Descendents"
$ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType,$inheritedobjectguid
$acl.AddAccessRule($ace)
Set-acl -aclobject $acl "ad:OU=xxx,DC=com"
The figure below shows the result of running the script above:
Figure 2.
In addition, if you want to assign other permissions, you can change the GUID values in the script above. The common GUID values are listed as below:
$guidChangePassword
= new-object Guid ab721a53-1e2f-11d0-9819-00aa0040529b
$guidLockoutTime
= new-object Guid 28630ebf-41d5-11d1-a9c1-0000f80367c1
$guidPwdLastSet
= new-object Guid bf967a0a-0de6-11d0-a285-00aa003049e2
$guidComputerObject
= new-object Guid bf967a86-0de6-11d0-a285-00aa003049e2
$guidUserObject
= new-object Guid bf967aba-0de6-11d0-a285-00aa003049e2
$guidLinkGroupPolicy
= new-object Guid f30e3bbe-9ff0-11d1-b603-0000f80367c1
$guidGroupPolicyOptions
= new-object Guid f30e3bbf-9ff0-11d1-b603-0000f80367c1
$guidResetPassword
= new-object Guid 00299570-246d-11d0-a768-00aa006e0529
$guidGroupObject
= new-object Guid BF967A9C-0DE6-11D0-A285-00AA003049E2
$guidContactObject
= new-object Guid 5CB41ED0-0E4C-11D0-A286-00AA003049E2
$guidOUObject
= new-object Guid BF967AA5-0DE6-11D0-A285-00AA003049E2
$guidPrinterObject
= new-object Guid BF967AA8-0DE6-11D0-A285-00AA003049E2
$guidWriteMembers
= new-object Guid bf9679c0-0de6-11d0-a285-00aa003049e2
$guidNull
= new-object Guid 00000000-0000-0000-0000-000000000000
$guidPublicInformation
= new-object Guid e48d0154-bcf8-11d1-8702-00c04fb96050
$guidGeneralInformation
= new-object Guid 59ba2f42-79a2-11d0-9020-00c04fc2d3cf
$guidPersonalInformation = new-object Guid 77B5B886-944A-11d1-AEBD-0000F80367C1
$guidGroupMembership
= new-object Guid bc0ac240-79a9-11d0-9020-00c04fc2d4cf
More information:
Add Object Specific ACEs using Active Directory Powershell
http://blogs.msdn.com/b/adpowershell/archive/2009/10/13/add-object-specific-aces-using-active-directory-powershell.aspx
Please click to vote if the post helps you. This can be beneficial to other community members reading the thread.The ActiveDirectoryAccessRule has more than one constructor, but yes, you've interpreted the one that takes six arguments correctly.
Those GUIDs are different (check just before the first dash). Creating that ACE will create an empty GUID for InheritedObjectType, though, because you're telling it to apply to the Object only ([System.DirectoryServices.ActiveDirectorySecurityInheritance]::None).
Since the ACE will only apply to the object, there's no need to worry about what types of objects will inherit it.
If you've got time, check out
this module. It will let you view the security descriptors in a much friendlier format. Try both version 3.0 and the version 4.0 preview:
Sample version 3.0:
# This is going to be kind of slow, and it will take a few seconds the first time
# you run it because it has to build the list of GUID <--> Property/Class/etc objects
Get-ADGroup GroupY |
Get-AccessControlEntry -ObjectAceType member -InheritedObjectAceType group -ActiveDirectoryRights WriteProperty
# Same as the previous command, except limit it to access granted to GroupX
Get-ADGroup GroupY |
Get-AccessControlEntry -ObjectAceType member -InheritedObjectAceType group -ActiveDirectoryRights WriteProperty -Principal GroupX
Here's version 4.0. It's way faster than 3.0, but it's missing the -ObjectAceType and -InheritedObjectAceType parameters on Get-AccessControlEntry (don't worry, when they come back they'll be better than in 3.0):
Get-ADGroup GroupY |
Get-AccessControlEntry
Get-ADGroup GroupY |
Get-AccessControlEntry -ActiveDirectoryRights WriteProperty
Get-ADGroup GroupY |
Get-AccessControlEntry -ActiveDirectoryRights WriteProperty -Principal GroupX
# You can do a Where-Object filter until the parameters are added back to Get-AccessControlEntry:
Get-ADGroup GroupY |
Get-AccessControlEntry -ActiveDirectoryRights WriteProperty |
where { $_.AccessMask -match "All Prop|member Prop" }
Get-ADGroup GroupY |
Get-AccessControlEntry -ActiveDirectoryRights WriteProperty |
where { $_.ObjectAceType -in ($null, [guid]::Empty, "bf9679c0-0de6-11d0-a285-00aa003049e2") }
Get-ADGroup GroupY |
Get-AccessControlEntry -ActiveDirectoryRights WriteProperty |
where { $_.AccessMask -match "All Prop|member Prop" -and $_.AppliesTo -match "group"}
That's just for viewing. Version 3.0 can add and remove access, or you can use New-AccessControlEntry to replace your call to New-Object, and you can still use Get-Acl and Set-Acl. The benefit to New-AccessControlEntry is that you can do something like this:
New-AccessControlEntry -Principal GroupX -ActiveDirectoryRights WriteProperty -ObjectAceType member -InheritedObjectAceType group #-AppliesTo Object
-
PowerShell and Active Directory
Jpacella wrote:
I get that they're trying to have personality and perhaps bring some color to dreadfully boring topics :) but I guess i'ma crabby old man and just want them to get to the point :)
I was that way at first, but got used to his personality. Besides those topics in the AD series are so interesting they don't need much animation lol. I've learned a great deal from that series so far, mainly the stale object section.If you work with Active Directory at all, which if you're a windows admin.. well you do. You HAVE TO WATCH THIS!! It teaches you almost everything you need to know about Active Directory and PowerShell. It's very applicable and interactive.
http://www.microsoftvirtualacademy.com/training-courses/using-powershell-for-active-directory
This topic first appeared in the Spiceworks Community -
How to list all the Fields for an Active Directory Object
How do I list all the fields that an Active Directory object contains? I know the most common ones, but would like to enumerate through all the fields and obtain the type of fields and their values...
Here is my complete code - I only put snippets so that the post was not too huge...
Option Explicit
Const ADS_SCOPE_SUBTREE = 2
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim adoCommand, adoConnection, adoRecordSet
Dim dtmDate, dtmValue
Dim j
Dim lngBias, lngBiasKey, lngHigh, lngLow, lngValue
Dim objADObject, objClass, objDate, objFile, objFSO, objRootDSE, objShell
Dim pathToScript
Dim strAdsPath, strConfig, strDNSDomain, strHex, strItem, strProperty, strValue
Dim strFilter, strQuery
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Wscript.Shell")
pathToScript = objShell.CurrentDirectory
Set objFile = objFSO.CreateTextFile(pathToScript & "\TestAD.csv")
' Determine Time Zone bias in local registry.
' This bias changes with Daylight Savings Time.
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For j = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(j) * 256^j)
Next
End If
' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
adoCommand.CommandText = "SELECT * FROM 'LDAP://" & strDNSDomain & "'WHERE objectClass=user'"
adoCommand.Properties("Page Size") = 1000
adoCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set adoRecordSet = adoCommand.Execute
Set adoRecordSet = adoCommand.Execute
adoRecordSet.MoveFirst
Do Until adoRecordSet.EOF
strAdsPath = adoRecordSet.Fields("ADsPath").Value
' Bind to Active Directory object specified.
Set objADObject = GetObject(strAdsPath)
Set objClass = GetObject(objADObject.Schema)
' Write which object is grabbed from AD
objFile.Write(Replace(strAdsPath, ",", ";;;"))
' Enumerate mandatory object properties.
For Each strProperty In objClass.MandatoryProperties
On Error Resume Next
strValue = objADObject.Get(strProperty)
If (Err.Number = 0) Then
On Error GoTo 0
If (TypeName(strValue) = "String") Or (TypeName(strValue) = "Long") Or (TypeName(strValue) = "Date") Then
objFile.Write("," & strProperty & "|||" & Replace(CStr(strValue), ",", ";;;"))
ElseIf (TypeName(strValue) = "Byte()") Then
strHex = OctetToHexStr(strValue)
objFile.Write("," & strProperty & "|||" & CStr(strHex))
ElseIf (TypeName(strValue) = "Variant()") Then
For Each strItem In strValue
On Error Resume Next
objFile.Write("," & strProperty & "|||" & Replace(CStr(strItem), ",", ";;;"))
If (Err.Number <> 0) Then
On Error GoTo 0
objFile.Write("," & strProperty & "|||Value cannot be displayed")
End If
On Error GoTo 0
Next
ElseIf (TypeName(strValue) = "Boolean") Then
objFile.Write("," & strProperty & "|||" & CBool(strValue))
Else
objFile.Write("," & strProperty & "|||Type:" & TypeName(strValue))
End If
Else
Err.Clear
sColl = objADObject.GetEx(strProperty)
If (Err.Number = 0) Then
For Each strItem In sColl
objFile.Write("," & strProperty & "|||" & CStr(strItem))
If (Err.Number <> 0) Then
objFile.Write("," & strProperty & "|||Value cannot be displayed")
End If
Next
On Error GoTo 0
Else
Err.Clear
Set objDate = objADObject.Get(strProperty)
If (Err.Number = 0) Then
lngHigh = objDate.HighPart
If (Err.Number = 0) Then
lngLow = objDate.LowPart
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
lngValue = (lngHigh * (2 ^ 32)) + lngLow
If (lngValue > 120000000000000000) Then
dtmValue = #1/1/1601# + (lngValue / 600000000 - lngBias) / 1440
On Error Resume Next
dtmDate = CDate(dtmValue)
If (Err.Number <> 0) Then
objFile.Write("," & strProperty & "|||<Never>")
Else
objFile.Write("," & strProperty & "|||" & CStr(dtmDate))
End If
Else
objFile.Write("," & strProperty & "|||" & FormatNumber(lngValue, 0))
End If
Else
objFile.Write("," & strProperty & "|||Value cannot be displayed")
End If
Else
On Error GoTo 0
objFile.Write("," & strProperty)
End If
On Error GoTo 0
End If
End If
Next
' Enumerate optional object properties.
For Each strProperty In objClass.OptionalProperties
On Error Resume Next
strValue = objADObject.Get(strProperty)
If (Err.Number = 0) Then
On Error GoTo 0
If (TypeName(strValue) = "String") Then
objFile.Write("," & strProperty & "|||" & Replace(CStr(strValue), ",", ";;;"))
ElseIf (TypeName(strValue) = "Long") Then
objFile.Write("," & strProperty & "|||" & Replace(CStr(strValue), ",", ";;;"))
ElseIf (TypeName(strValue) = "Date") Then
objFile.Write("," & strProperty & "|||" & Replace(CStr(strValue), ",", ";;;"))
ElseIf (TypeName(strValue) = "Byte()") Then
strHex = OctetToHexStr(strValue)
objFile.Write("," & strProperty & "|||" & CStr(strHex))
ElseIf (TypeName(strValue) = "Variant()") Then
For Each strItem In strValue
On Error Resume Next
objFile.Write("," & strProperty & "|||" & Replace(CStr(strItem), ",", ";;;"))
If (Err.Number <> 0) Then
On Error GoTo 0
objFile.Write("," & strProperty & "|||Value cannot be displayed")
End If
On Error GoTo 0
Next
ElseIf (TypeName(strValue) = "Boolean") Then
objFile.Write("," & strProperty & "|||" & CBool(strValue))
Else
objFile.Write("," & strProperty & "|||Type:" & TypeName(strValue))
End If
Else
Err.Clear
sColl = objADObject.GetEx(strProperty)
If (Err.Number = 0) Then
For Each strItem In sColl
objFile.Write("," & strProperty & "|||" & CStr(strItem))
If (Err.Number <> 0) Then
objFile.Write("," & strProperty & "|||Value cannot be displayed")
End If
Next
On Error GoTo 0
Else
Err.Clear
Set objDate = objADObject.Get(strProperty)
If (Err.Number = 0) Then
lngHigh = objDate.HighPart
If (Err.Number = 0) Then
lngLow = objDate.LowPart
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
lngValue = (lngHigh * (2 ^ 32)) + lngLow
If (lngValue > 120000000000000000) Then
dtmValue = #1/1/1601# + (lngValue / 600000000 - lngBias) / 1440
On Error Resume Next
dtmDate = CDate(dtmValue)
If (Err.Number <> 0) Then
objFile.Write("," & strProperty & "|||<Never>")
Else
objFile.Write("," & strProperty & "|||" & CStr(dtmDate))
End If
Else
objFile.Write("," & strProperty & "|||" & lngValue)
End If
Else
objFile.Write("," & strProperty & "|||Value cannot be displayed")
End If
Else
On Error GoTo 0
objFile.Write("," & strProperty & "||| ")
End If
On Error GoTo 0
End If
End If
Next
objFile.WriteLine("")
adoRecordSet.MoveNext
Loop
objFile.Close
' Function to convert OctetString (Byte Array) to a hex string.
Function OctetToHexStr(arrbytOctet)
Dim k
OctetToHexStr = ""
For k = 1 To Lenb(arrbytOctet)
OctetToHexStr = OctetToHexStr _
& Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2)
Next
End Function
I have been able to obtain all the Computer, Contact, Group and OU objects without issue with this code... -
The Netscape/NDS AddUser implements inetOrgPerson, and some other objects/Attributes not implemented in Active Directory Object Attributes, and I receive errors about the Attributes. Could you tell me the correct Attribute definition for the default DS, to add a user?
Unsure what you mean. iDS 5 implements the inetOrgPerson as of the RFC. It is made of 4 objects top, person, organizationPerson and inetOrgPerson. The user object in MAD using many more MS specifi attributes in the top class. (53 extras)
-
Renaming Active Directory object
Hi guys,
I have search all over the internet to find a solution for this, but I didn't find anything ... is there any way to rename an object in AD?
For example:
CN=my user name, CN=Users, DC=myCompany, DC=comneeds to be renamed to:
CN=John Smith, CN=Users, DC=myCompany, DC=comSo I am trying to change the CN, but I can't figure this out!!!
I know that this is possible because Microsoft has this functionality in C#
try
// Bind to the user object to modify.
DirectoryEntry child = new DirectoryEntry("LDAP://CN=My User Name,OU=Marketing,DC=fabrikam,DC=com");
// Rename the object to Jeff Smith.
child.Rename("CN=New User Name");
catch (Exception Exception1)
// If a COMException is thrown, then the following code can capture the text of the error.
// For more information about handling COM exceptions, see Handling Errors.
System.Runtime.InteropServices.COMException COMEx =
(System.Runtime.InteropServices.COMException) Exception1;
Console.WriteLine(COMEx.ErrorCode);
)Thanks in advanceOf course there is a way to rename an Active Driectory object !
You obviously didn't search very thoroughly, else you would have at least looked up the JNDI tutorial in which you would have found context.rename()
Renaming an object is similar to a move operation as described in a previous post http://forum.java.sun.com/thread.jspa?threadID=628913&tstart=15
Again assuming you have an initial context, the code would sort of look likeString oldUserName = "CN=Albert Einstein";
String newUserName = "CN=Isaac Newton";
String ouPath= "OU=Research,DC=antipodes,DC=com";
LdapContext ouCtx = (LdapContext)ctx.lookup(ouPath);
ouCtx.rename(oldUserName,newUserName); -
Active Directory Object Properties
Maybe I am completely missing something, but is there no way to create an array of properties from get-aduser? I need to iterate through the user properties to find certain criteria. Even if I do:
$user = get-aduser $username -properties *
$user.count
The count returns 1. Now, I know it is only 1 user object, but is there a way to iterate through each property?
Thanks!
TonySorry, I have not yet opened a topic and asked a question, I don't know how.
To answer the question "is there a way to iterate through each property?"
Here is one way. It iterates through the properties (of any object) and create the properties
to create a PS-Object
PS C:\>
Function Get-PSObjectFromObject
[CmdletBinding()]
[OutputType([string])]
param
[Parameter(Mandatory=$true,
ValueFromPipeline=$false,
ValueFromPipelineByPropertyName=$false,
ValueFromRemainingArguments=$false,
Position=0,
ParameterSetName='Object')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Object]$Object
Try
$Members=Get-Member -InputObject $Object
$ValidPropertyType = @{"{get;set;}"=$True;"{get;}"=$True;}
$ValidReturnType = @{"bool"=$True;"byte"=$True;"string"=$True;"string[]"=$True;
"int"=$True;"int16"=$True;"int32"=$True;"int64"=$True;
"uint"=$True;"uint16"=$True;"uint32"=$True;"uint64"=$True;
"datetime"=$True;"timespan"=$True;
"system.boolean"=$True;"system.byte"=$True;"system.string"=$True;"system.string[]"=$True;
"system.int"=$True;"system.int16"=$True;"system.int32"=$True;"system.int64"=$True;
"system.uint"=$True;"system.uint16"=$True;"system.uint32"=$True;"system.uint64"=$True;
"system.datetime"=$True;"system.timespan"=$True
[string]$String=""
$String=$String+"New-Object PSObject -Property ([Ordered]@{ `r`n"
ForEach ($Member in $Members)
IF ($Member.MemberType -EQ "Property")
[string]$Name=$Member.Name
IF ($Name.Substring(1,1) -NE "_")
IF (-NOT $Name.Contains("-"))
[String[]]$Definition=$Member.Definition.Split(" ")
[string]$PropertyType=$Definition[2]
IF ($ValidPropertyType[$PropertyType])
$ReturnType=$Definition[0]
If ($ValidReturnType[$ReturnType])
$String=$String+" $Name="+"$"+"Object.$Name `r`n"
$String=$String+"}) `r`n"
$String
Catch [System.Exception]
Write-Host $_.Exception.Message
$Object = Get-aduser "Administrator" -Properties *
$PSProperties = Get-PSObjectFromObject $Object
$PSObject = Invoke-Expression $PSProperties
"***********This is PSObject definition"
$PSProperties
"***********This is PSObject"
$PSObject
***********This is PSObject definition
New-Object PSObject -Property ([Ordered]@{
AccountExpirationDate=$Object.AccountExpirationDate
accountExpires=$Object.accountExpires
AccountLockoutTime=$Object.AccountLockoutTime
AccountNotDelegated=$Object.AccountNotDelegated
adminCount=$Object.adminCount
AllowReversiblePasswordEncryption=$Object.AllowReversiblePasswordEncryption
BadLogonCount=$Object.BadLogonCount
badPasswordTime=$Object.badPasswordTime
badPwdCount=$Object.badPwdCount
CannotChangePassword=$Object.CannotChangePassword
CanonicalName=$Object.CanonicalName
City=$Object.City
CN=$Object.CN
codePage=$Object.codePage
Company=$Object.Company
Country=$Object.Country
countryCode=$Object.countryCode
Created=$Object.Created
createTimeStamp=$Object.createTimeStamp
Deleted=$Object.Deleted
Department=$Object.Department
Description=$Object.Description
DisplayName=$Object.DisplayName
DistinguishedName=$Object.DistinguishedName
Division=$Object.Division
DoesNotRequirePreAuth=$Object.DoesNotRequirePreAuth
EmailAddress=$Object.EmailAddress
EmployeeID=$Object.EmployeeID
EmployeeNumber=$Object.EmployeeNumber
Enabled=$Object.Enabled
Fax=$Object.Fax
GivenName=$Object.GivenName
HomeDirectory=$Object.HomeDirectory
HomedirRequired=$Object.HomedirRequired
HomeDrive=$Object.HomeDrive
HomePage=$Object.HomePage
HomePhone=$Object.HomePhone
Initials=$Object.Initials
instanceType=$Object.instanceType
isCriticalSystemObject=$Object.isCriticalSystemObject
isDeleted=$Object.isDeleted
LastBadPasswordAttempt=$Object.LastBadPasswordAttempt
LastKnownParent=$Object.LastKnownParent
lastLogoff=$Object.lastLogoff
lastLogon=$Object.lastLogon
LastLogonDate=$Object.LastLogonDate
lastLogonTimestamp=$Object.lastLogonTimestamp
LockedOut=$Object.LockedOut
logonCount=$Object.logonCount
LogonWorkstations=$Object.LogonWorkstations
Manager=$Object.Manager
MNSLogonAccount=$Object.MNSLogonAccount
MobilePhone=$Object.MobilePhone
Modified=$Object.Modified
modifyTimeStamp=$Object.modifyTimeStamp
Name=$Object.Name
ObjectCategory=$Object.ObjectCategory
ObjectClass=$Object.ObjectClass
Office=$Object.Office
OfficePhone=$Object.OfficePhone
Organization=$Object.Organization
OtherName=$Object.OtherName
PasswordExpired=$Object.PasswordExpired
PasswordLastSet=$Object.PasswordLastSet
PasswordNeverExpires=$Object.PasswordNeverExpires
PasswordNotRequired=$Object.PasswordNotRequired
POBox=$Object.POBox
PostalCode=$Object.PostalCode
PrimaryGroup=$Object.PrimaryGroup
primaryGroupID=$Object.primaryGroupID
ProfilePath=$Object.ProfilePath
ProtectedFromAccidentalDeletion=$Object.ProtectedFromAccidentalDeletion
pwdLastSet=$Object.pwdLastSet
SamAccountName=$Object.SamAccountName
sAMAccountType=$Object.sAMAccountType
ScriptPath=$Object.ScriptPath
sDRightsEffective=$Object.sDRightsEffective
SmartcardLogonRequired=$Object.SmartcardLogonRequired
State=$Object.State
StreetAddress=$Object.StreetAddress
Surname=$Object.Surname
Title=$Object.Title
TrustedForDelegation=$Object.TrustedForDelegation
TrustedToAuthForDelegation=$Object.TrustedToAuthForDelegation
UseDESKeyOnly=$Object.UseDESKeyOnly
userAccountControl=$Object.userAccountControl
UserPrincipalName=$Object.UserPrincipalName
uSNChanged=$Object.uSNChanged
uSNCreated=$Object.uSNCreated
whenChanged=$Object.whenChanged
whenCreated=$Object.whenCreated
***********This is PSObject
AccountExpirationDate :
accountExpires : 9223372036854775807
AccountLockoutTime :
AccountNotDelegated : False
adminCount : 1
AllowReversiblePasswordEncryption : False
BadLogonCount : 0
badPasswordTime : 130524210883000074
badPwdCount : 0
CannotChangePassword : False
CanonicalName : Contoso.com/Users/Administrator
City :
CN : Administrator
codePage : 0
Company :
Country :
countryCode : 0
Created : 6/21/2014 12:48:03 AM
createTimeStamp : 6/21/2014 12:48:03 AM
Deleted :
Department :
Description : Built-in account for administering the computer/domain
DisplayName :
DistinguishedName : CN=Administrator,CN=Users,DC=Contoso,DC=com
Division :
DoesNotRequirePreAuth : False
EmailAddress :
EmployeeID :
EmployeeNumber :
Enabled : True
Fax :
GivenName :
HomeDirectory :
HomedirRequired : False
HomeDrive :
HomePage :
HomePhone :
Initials :
instanceType : 4
isCriticalSystemObject : True
isDeleted :
LastBadPasswordAttempt : 8/13/2014 9:31:28 AM
LastKnownParent :
lastLogoff : 0
lastLogon : 130530452556502145
LastLogonDate : 8/12/2014 2:27:39 AM
lastLogonTimestamp : 130523092594640653
LockedOut : False
logonCount : 714
LogonWorkstations :
Manager :
MNSLogonAccount : False
MobilePhone :
Modified : 8/12/2014 2:27:39 AM
modifyTimeStamp : 8/12/2014 2:27:39 AM
Name : Administrator
ObjectCategory : CN=Person,CN=Schema,CN=Configuration,DC=Contoso,DC=com
ObjectClass : user
Office :
OfficePhone :
Organization :
OtherName :
PasswordExpired : False
PasswordLastSet : 6/14/2014 4:55:33 AM
PasswordNeverExpires : True
PasswordNotRequired : False
POBox :
PostalCode :
PrimaryGroup : CN=Domain Users,CN=Users,DC=Contoso,DC=com
primaryGroupID : 513
ProfilePath :
ProtectedFromAccidentalDeletion : False
pwdLastSet : 130472205339962382
SamAccountName : Administrator
sAMAccountType : 805306368
ScriptPath :
sDRightsEffective : 15
SmartcardLogonRequired : False
State :
StreetAddress :
Surname :
Title :
TrustedForDelegation : False
TrustedToAuthForDelegation : False
UseDESKeyOnly : False
userAccountControl : 66048
UserPrincipalName :
uSNChanged : 113679
uSNCreated : 8196
whenChanged : 8/12/2014 2:27:39 AM
whenCreated : 6/21/2014 12:48:03 AM
PS C:\>
The GUI version of this will be uploaded within a day or two. -
Logoncount Attribute on Computer objects in Active Directory
Hello,
I have one question about the logoncount Attribute on Active Directory objects. As I understood on user objects this attribute counts the number of logons per DC (because it is not replicating).
My question is:
What exactly is count here on computer objects?
I can see that on a Domain Controller computer object the logoncount is high for the DC itself and low on the other DC objects.
Thank you.
Regards
DennisHere is an old thread. You will see some of the explanation from our own Richard :)
http://www.techtalkz.com/windows-server-2003/500367-attributes-update-during-computer-logon.html
Santhosh Sivarajan | Houston, TX | www.sivarajan.com
ITIL,MCITP,MCTS,MCSE (W2K3/W2K/NT4),MCSA(W2K3/W2K/MSG),Network+,CCNA
Windows Server 2012 Book - Migrating from 2008 to Windows Server 2012
Blogs: Blogs
Twitter: Twitter
LinkedIn: LinkedIn
Facebook: Facebook
Microsoft Virtual Academy:
Microsoft Virtual Academy
This posting is provided AS IS with no warranties, and confers no rights. -
Hi All,
I am trying to configure SharePoint Profile service. We would like a straightforward profile import from Active Directory.
On the "Configure Synchronization Settings" page, we have chosen the option "Use SharePoint Active Directory Import" option.
We have created a connection to the Active Directory using Configure Synchronization Connections page. We have specified the account that would be used for the import process.
Question:
I would like to confirm whether the account configured for the profile import need any special privileges when using "Use SharePoint Active Directory Import" option ?
Thanks,
SaurabhGrant Replicate Directory Changes permission on a domain
To do this please follows below procedure
On the domain controller, click Start, click Administrative Tools, and then click Active Directory Users and Computers.
In Active Directory Users and Computers, right-click the domain, and then click Delegate Control.
On the first page of the Delegation of Control Wizard, click Next.
On the Users or Groups page, click Add.
Type the name of the synchronization account, and then click OK.
Click Next.
On the Tasks to Delegate page, select Create a custom task to delegate, and then click Next.
On the Active Directory Object Type page, select This folder, existing objects in this folder, and creation of new objects in this folder, and then clickNext.
On the Permissions page, in the Permissions box, select Replicating Directory Changes (select Replicate Directory Changes on
Windows Server 2003), and then click Next.
Click Finish.
Thanks & Regards
ShivaPrasad Pola
SharePoint Developer -
How to update users to Active Directory using Hyena Active Task List?
Kevin,
thanks for your input. I was able to firgured it out. It need the full path. with the CN=John Doe
Working like a charm!! thx!!http://www.systemtools.com/HyenaHelp/active_editor.htm"Each Active Directory object is identifiable by its directory path, called the ADsPath. A special symbol, %ADSPATH%, can be inserted in the field order list that can be associated with the directory path in the import file. The ADsPath doesNOThave to be one of the attributes for the directory objects in the Editor if the ADsPath is used as the Key Field in the import file.Using an ADsPath as a match field can be difficult, as it is a long and complex string, and if special characters are used in some directory fields, Active Directory will automatically insert additional special characters into the ADsPath. One method of getting the ADsPath into a file for directory objects is to use Hyena's Edit Copy dialog. A special symbol, %ADSPATH%, can be added to any Active Directory copied...
-
Exchange trying to resolve external e-mail addresses in local Active Directory
Hi
On all of my Mailbox Database servers, i'm getting the following warning in my Application log:
Level: Warning
Source: MSExchange Mid-Tier Storage
EventID: 2009
Message:
[Process:w3wp PID:6032 Thread:89] Error occurred while resolving the Active Directory object for from email address field: '[email protected]'. Audit log will not be generated for this case. Exception details:
Microsoft.Exchange.Data.Storage.ObjectNotFoundException: The Active Directory user wasn't found.
at Microsoft.Exchange.Data.Storage.ExchangePrincipalFactory.FromProxyAddress(IRecipientSession session, String proxyAddress, RemotingOptions remotingOptions)
at Microsoft.Exchange.Data.Storage.ExchangePrincipalFactory.FromProxyAddress(ADSessionSettings adSettings, String proxyAddress, RemotingOptions remotingOptions)
at Microsoft.Exchange.Data.Storage.ExchangePrincipal.FromProxyAddress(ADSessionSettings adSettings, String proxyAddress)
at Microsoft.Exchange.Data.Storage.COWAudit.GetSubmitEffectiveMailboxOwner(MailboxSession session, CallbackContext callbackContext)
I have three Exchange Server 2013 MBX/CAS servers, and two Exchange Server 2013 Edge Transport servers in front of them.
As mentioned earlier, this warning is on all three of the MBX/CAS servers. The external e-mail address vary.
I've used the Get-MessageTrackingLog to debug, and I can see that this error comes when an internal user sends a "Meeting Forward Notification" to an external e-mail address. Exchange tries to resolve the external e-mail address in Active Directory
and throws this warning, for some reason.
Is there anyone that knows how to fix this?Hi Allen
Sorry for the late reply.
1. No it's not. It gets the EventID "HADISCARD" and SourceContext "ExplicitlyDiscarded". Here's an example:
RunspaceId : a25e81b2-9f4a-49f2-895b-xxxxxxxxxxxx
Timestamp : 09-02-2015 13:01:02
ClientIp :
ClientHostname :
ServerIp :
ServerHostname : MBX01
SourceContext : ExplicitlyDiscarded
ConnectorId :
Source : SMTP
EventId : HADISCARD
InternalMessageId : 8907762172963
MessageId : <[email protected]>
Recipients : {[email protected]}
RecipientStatus : {}
TotalBytes : 17347
RecipientCount : 1
RelatedRecipientAddress :
Reference :
MessageSubject : Meeting Forward Notification: A subject
Sender : [email protected]
ReturnPath : [email protected]
Directionality : Originating
TenantId :
OriginalClientIp :
MessageInfo :
MessageLatency :
MessageLatencyType : None
EventData : {[DeliveryPriority, None], [PrioritizationReason, ShadowRedundancy]}
2. Yes, and other mails are routed to our Edge Transport Servers, and from there to Office 365 (Exchange Online Protection). It's only occurs when sending Meeting Forward Notifications, Accepting meetings, and so fourth - and it all comes from Outlook 2013
clients (RPC over HTTPS). -
Show Active Directory Property Page
Hello everybody,
I hope this topic is published in the correct forum. I try to find the API which shows the native property page of Active Directory objects. If possible with an example (VB.Net)? There exists an similar function named "openquerywindow" which
used by dsquery.dll. Is there a library function that would do this (e.g.
activeds.dll or dsprop.dll)?
Thanks in advance,
MatthiasHello Matthias,
>> I try to find the API which shows the native property page of Active Directory objects.
I do not quite understand what the native property page of Active Directory objects is, if it means the native Active Directory Service Interfaces (ADSI) object, you then could get it by using
DirectoryEntry class:
DirectoryEntry.NativeObject Property
If not, since it is not very clear what you are trying to query from the active directory, there is a list which you could query from .NET, you could check if there are features that you want:
Search Active Directory
Here is a blog which provides a detail description about how to: Querying Active Directory which I think could be helpful.
Regards.
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click
HERE to participate the survey. -
Hi Scripting Guy. I am a Server Administrator who is very familiar with Active Directory, but new to PowerShell. Like many SysAdmins, I often need to create multiple accounts (ranging from 3-200) and add them multiple groups (ranging
from 1 - 100). Previously I used VBS scripts in conjunction with an Excel .XLS file (not CSV file). Since VBS is essentially out the door and PowerShell is in - I am having to re-create everthing.
I have written a PowerShell script that bulk creates my users and adds them to their corresponding groups - however, this can only use a CSV file (NOT an XLS file). I understand that "CSV is much easier to use than Excel worksheets", but
most times I have three sets of nearly identical groups (for Dev, QA and Prod). Performing Search and Replace on the Excel template across all four Worksheets ensures the names used are consistent throughout the three environments.
I know each Excel Worksheet can be exported as a separate CSV file and then use the PowerShell scripts as is, but since I am not the only SysAdmin who will be using these it leads to "unnecessary time lost", not to mention the reality that even
though you clearly state "These tabs need to be exported using this naming standard" (to work with the PowerShell scripts) that is not the result.
I've been tasked to find a way to modify my existing PowerShell/CSV scripts to work with Excel spreadsheets/workbooks instead - with no success. I have run across many articles/forums/scirpts that let you update Excel or export AD data into an Excel
spreadsheet (even specifying the worksheet, column and row) - but nothing for what I am trying to do.
I can't imagine that I am the ONLY person who is in this situation/has this need. So, I am hoping you can help. How do I modify my existing scripts to reference "use this Excel spreadsheet, and this specific worksheet in the spreadsheet
prior to performing the New-ADUser/Add-ADGroupMember commands".
For reference, I am including Worksheet/Column names of my Excel Spreadsheet Template as well as the first part of my PowerShell script. M-A-N-Y T-H-A-N-K-S in advance.
Worksheet: Accounts
Columns: samAccountName, CN_DisplayName_Name, sn_LastName, givenName_FirstName, Password, Description, TargetOU
Worksheets: DevGroups / QAGroups / ProdGroups
Columns: GroupName, Members, MemberOf, Description, TargetOU
# Load PowerShell Active Directory module
Write-Host "Loading Active Directory PowerShell module." -foregroundcolor DarkCyan # -backgroundcolor Black
Import-Module ActiveDirectory
Write-Host " "
# Set parameter for location of CSV file (so source file only needs to be listed once).
$path = ".\CreateNewUsers-CSV.csv"
# Import CSV file as data source for remaining script.
$csv = Import-Csv -path $path | ForEach-Object {
# Add '@saccounty.net' suffix to samAccountName for UserPrincipalName
$userPrincinpal = $_."samAccountName" + "@saccounty.net"
# Create and configure new AD User Account based on information from the CSV source file.
Write-Host " "
Write-Host " "
Write-Host "Creating and configuring new user account from the CSV source file." -foregroundcolor Cyan # -backgroundcolor Black
New-ADUser -Name $_."cn_DisplayName_Name" `
-Path $_."TargetOU" `
-DisplayName $_."cn_DisplayName_Name" `
-GivenName $_."givenName_FirstName" `
-SurName $_."sn_LastName" `
-SamAccountName $_."samAccountName" `
-UserPrincipalName $userPrincinpal `Here is the same script as a function:
Function Get-ExcelSheet{
Param(
$fileName = 'C:\scripts\test.xls',
$sheetName = 'csv2'
$conn = New-Object System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = $fileName;Extended Properties=Excel 8.0")
$cmd=$conn.CreateCommand()
$cmd.CommandText="Select * from [$sheetName$]"
$conn.open()
$cmd.ExecuteReader()
It is called like this:
Get-ExcelSheet -filename c:\temp\myfilename.xslx -sheetName mysheet
Do NOT change anything in the function and post the exact error. If you don't have Office installed correctly or are running 64 bits with a 32 bit session you will have to adjust your system.
¯\_(ツ)_/¯
HI JRV,
My apologies for not responding sooner - I was pulled off onto another project this week. I have included and called your Get-ExcelSheet function as best as I could...
# Load PowerShell Active Directory module
Write-Host "Loading Active Directory PowerShell module." -foregroundcolor DarkCyan # -backgroundcolor Black
Import-Module ActiveDirectory
Write-Host " "
# JRV This Function Loads the Excel Reader
Function Get-ExcelSheet{
Param(
$fileName = 'C:\scripts\test.xls',
$sheetName = 'csv2'
$conn = New-Object System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = $fileName;Extended Properties=Excel 8.0")
$cmd=$conn.CreateCommand()
$cmd.CommandText="Select * from [$sheetName$]"
$conn.open()
$cmd.ExecuteReader()
# Set parameter for location of CSV file (so source file only needs to be listed once) as well as Worksheet Names.
$sourceFile = ".\NewDocClass-XLS-Test.xlsx"
# Add '@saccounty.net' suffix to samAccountName for UserPrincipalName
$userPrincinpal = $_."samAccountName" + "@saccounty.net"
# Combine GivenName & SurName for DisplayName
$displayName = $_."sn_LastName" + ". " + $_."givenName_FirstName"
# JRV Call the Get-ExcelSheet function, providing FileName and SheetName values
# Pipe the data from source for remaining script.
Get-ExcelSheet -filename "E:\AD_Bulk_Update\NewDocClass-XLS-Test.xlsx" -sheetName "Create DocClass Accts" | ForEach-Object {
# Create and configure new AD User Account based on information from the CSV source file.
Write-Host " "
Write-Host " "
Write-Host "Creating and configuring new user account from the CSV source file." -foregroundcolor Cyan # -backgroundcolor Black
New-ADUser -Name ($_."sn_LastName" + ". " + $_."givenName_FirstName") `
-SamAccountName $_."samAccountName" `
-UserPrincipalName $userPrincinpal `
-Path $_."TargetOU" `
Below is the errors I get:
Exception calling "Open" with "0" argument(s): "The 'Microsoft.Jet.OLEDB.4.0'
provider is not registered on the local machine."
At E:\AD_Bulk_Update\Create-BulkADUsers-XLS.ps1:39 char:6
+ $conn.open()
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
Exception calling "ExecuteReader" with "0" argument(s): "ExecuteReader
requires an open and available Connection. The connection's current state is
closed."
At E:\AD_Bulk_Update\Create-BulkADUsers-XLS.ps1:40 char:6
+ $cmd.ExecuteReader()
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException -
Using PowerShell to import CSV data from Vendor database to manipulate Active Directory Users
Hello,
I have a big project I am trying to automate. I am working in a K-12 public education IT Dept. and have been tasked with importing data that has been exported from a vendor database via .csv file into Active Directory to manage student accounts.
My client wants to use this data to make bulk changes to student user accounts in AD such as moving accounts from one OU to another, modifying account attributes based on State ID, lunchroom ID, School, Grade, etc. and adding new accounts / disabling
accounts for students no longer enrolled.
The .csv that is exported doesn't have headers that match up with what is needed for importing in AD, so those have to be modified in this process, or set as variables to get the correct info into the correct attributes in AD or else this whole project is
a bust. He is tired of manually manipulating the .csv data and trying to get it onto AD with few or no errors, hence the reason it has been passed off to me.
Since this information changes practically daily, I need a way to automate user management by accomplishing the following on a scheduled basis.
Process must:
Check to see if Student Number already exists
If yes, then modify account
Update {School Name}, {Site Code}, {School Number}, {Grade Level} (Variables)
Add correct group memberships (School / Grade Specific)
Move account to correct OU (OU={Grade},OU=Students,OU=Users,OU={SiteCode},DC=Domain,DC=net)
Remove incorrect group memberships (School / Grade Specific)
Set account status (enabled / disabled)
If no, create account
Import Student #
Import CNP #
Import Student name
Extract First and Middle initial
If duplicate name exists
Create log entry for review
Import School, School Number, Grade Level
Add to correct Group memberships (School / Grade Specific)
Set correct OU (OU={Grade},OU=Students,OU=Users,OU={SiteCode},DC=Domain,DC=net)
Set account Status
I am not familiar with Powershell, but have researched enough to know that it will be the best option for this project. I have seen some partial solutions in VB, but I am more of an infrastructure person instead of scripting / software development.
I have just started creating a script and already have hit a snag. Maybe one of you could help.
#Connect to Active Directory
Import-Module ActiveDirectory
# Import iNOW user information
$Users = import-csv C:\ADUpdate\INOW_export.csv
#Check to see if the account already exists in AD
ForEach ( $user in $users )
#Assign the content to variables
$Attr_employeeID = $users."Student Number"
$Attr_givenName = $users."First Name"
$Attr_middleName = $users."Middle Name"
$Attr_sn = $users."Last Name"
$Attr_postaldeliveryOfficeName = $users.School
$Attr_company = $users."School Number"
$Attr_department = $users."Grade Level"
$Attr_cn = $Attr_givenName.Substring(0,1) + $Attr_middleName.Substring(0,1) + $Attr_sn
IF (Get-ADUser $Attr_cn)
{Write-Host $Attr_cn already exists in Active DirectoryThank you for helping me with that before it became an issue later on, however, even when modified to be $Attr_sAMAaccountName i still get errors.
#Connect to Active Directory
Import-Module ActiveDirectory
# Import iNOW user information
$Users = import-csv D:\ADUpdate\Data\INOW_export.csv
#Check to see if the account already exists in AD
ForEach ( $user in $users )
#Assign the content to variables
$Attr_employeeID = $users."Student Number"
$Attr_givenName = $users."First Name"
$Attr_middleName = $users."Middle Name"
$Attr_sn = $users."Last Name"
$Attr_postaldeliveryOfficeName = $users.School
$Attr_company = $users."School Number"
$Attr_department = $users."Grade Level"
$Attr_sAMAccountName = $Attr_givenName.Substring(0,1) + $Attr_middleName.Substring(0,1) + $Attr_sn
IF (Get-ADUser $Attr_sAMAccountName)
{Write-Host $Attr_sAMAccountName already exists in Active Directory
PS C:\Windows\system32> D:\ADUpdate\Scripts\INOW-AD.ps1
Get-ADUser : Cannot convert 'System.Object[]' to the type 'Microsoft.ActiveDirectory.Management.ADUser'
required by parameter 'Identity'. Specified method is not supported.
At D:\ADUpdate\Scripts\INOW-AD.ps1:28 char:28
+ IF (Get-ADUser $Attr_sAMAccountName)
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.ActiveDirectory.Management.Commands.GetAD
User -
Hey Scripting Guys,
I have been in and out of Powershell last few years, not that great at it tbh !!! I'm looking for advice on how I can as in Title, Create a Powershell script to Scan Active Directory Attributes for Country and Department ,Then add to Group then add to Distribution
list based on Region/Country
I was thinking along the lines of get-aduser -LDAPFilter "(department=SALES France) and adding a where clause for country.
Any help would be great.
DecSo I have tried a few variations but get errors on both
get-aduser -LDAPFilter "(&(department=SALES)(c=us))" | Add-ADPrincipalGroupMembership -MemberOf "testgroup"
get-aduser -LDAPFilter "(&(department=SALES)(c=fr))" | Add-ADGroupMember -identity "testgroup"
Add-ADPrincipalGroupMembership : Object reference not set to an instance of an
object.
At line:1 char:86
+ get-aduser -LDAPFilter "(&(department=SALES)(c=fr))" | Add-ADPrincipalGroupMe
mbership <<<< -MemberOf "testgroup"
+ CategoryInfo : NotSpecified: (:) [Add-ADPrincipalGroupMembershi
p], NullReferenceException
+ FullyQualifiedErrorId : Object reference not set to an instance of an ob
ject.,Microsoft.ActiveDirectory.Management.Commands.AddADPrincipalGroupMem
bership
Maybe you are looking for
-
Clip Inspector in iMovie 10.0.6
Where I can find 'Clip Inspector' in iMovie 10.0.6? or there are other ways to editing color (Grading). I wanted to make a 'Film Look' on my vid, can i do it in iMovie 10.0.6? thank you
-
IPhone error message in iTunes, frozen iPhone
Bit of background, I have to iPhone 3GS with 4.1.something. The computer it's synced to is running windows XP. Two weeks ago my lock button stopped working, I now have to leave it out for a minute to lock (although the button still works when the pho
-
I have run the rapidwiz install but it has now given me the following error (even though there is a listener running) - Can anyone help? command: cmd.exe /c F:\OracleApps\startCD\Disk1\rapidwiz\bin\riwTDBup.cmd f:\oracle\VIS\db\tech_st\11.1.0\VIS_uk0
-
I'm a dumb blonde, just paid for a online number which I don't need ( I didn't read the info first) can I cancel it and have the money paid back into my skype credit? What I really need is a skype to go number
-
Im tryinging to sync my new iphone 4 and I keep getting error message saying can't connect to store -9808