March 2012 - Posts

PowerShell in Practice offer today only

Manning have PowerShell in Practice on a half price offer today. Go to www.manning.com and use code dotd0330cc when ordering

UK PowerShell Group March 2012 meeting recording

 

The recording, slides and demo script from the session on CIM cmdlets – Tuesday 27 March is available

https://skydrive.live.com/?cid=43cfa46a74cf3e96#cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212955

Enjoy

PowerShell Deep Dive 2012 Agenda

The agenda for the PowerShell Deep Dive next month has just been published on the PowerShell team blog

http://blogs.msdn.com/b/powershell/archive/2012/03/26/schedule-for-the-upcoming-powershell-deep-dive-and-a-few-videos-from-frankfurt.aspx

If you are already booked to go – looking forward to meeting you.  If you’re thinking of going last years event was amazing. If you are interested in PowerShell it is the place to be

Attributes returned by the cmdlets

A question on the forum about the default properties returned by Get-ADUser started me thinking about the differences between the Microsoft cmdlets and the Quest cmdlets.

So for starters the default display:

Get-ADUser richard
Get-QADUser richard

Get-AdUser Get-QADUser
DistinguishedName DN
Enabled  
GivenName  
Name Name
ObjectClass Type
ObjectGUID  
SamAccountName  
SID  
Surname  
UserPrincipalName  

The full set of attributes returned by default

Get-ADUser richard | fl *   Get-QADUser richard | fl *
DistinguishedName   objectClass
Enabled   objectSid
GivenName   givenName
Name   whenCreated
ObjectClass   objectGUID
ObjectGUID   whenChanged
SamAccountName   l
SID   mail
Surname   edsvaNamingContextDN
UserPrincipalName   facsimileTelephoneNumber
PropertyNames   sn
PropertyCount   mobile
    physicalDeliveryOfficeName
    telephoneNumber
    st
    wWWHomePage
    City
    Company
    Department
    Email
    Fax
    FirstName
    HomePhone
    Initials
    LastName
    LogonName
    Manager
    MobilePhone
    Office
    Pager
    PhoneNumber
    PostalCode
    PostOfficeBox
    PrimaryGroupId
    StateOrProvince
    StreetAddress
    Title
    WebPage
    HomeDirectory
    HomeDrive
    ProfilePath
    LogonScript
    UserPrincipalName
    TsProfilePath
    TsHomeDirectory
    TsHomeDrive
    TsAllowLogon
    TsRemoteControl
    TsMaxDisconnectionTime
    TsMaxConnectionTime
    TsMaxIdleTime
    TsReconnectionAction
    TsBrokenConnectionAction
    TsConnectClientDrives
    TsConnectPrinterDrives
    TsDefaultToMainPrinter
    TsWorkDirectory
    TsInitialProgram
    AccountExpires
    PasswordLastSet
    PasswordAge
    PasswordExpires
    LastLogonTimestamp
    LastLogon
    LastLogoff
    AccountIsDisabled
    AccountIsLockedOut
    PasswordNeverExpires
    UserMustChangePassword
    AccountIsExpired
    PasswordIsExpired
    AccountExpirationStatus
    PasswordStatus
    DeprovisionStatus
    NTAccountName
    SamAccountName
    Security
    Domain
    LastKnownParent
    MemberOf
    NestedMemberOf
    Notes
    AllMemberOf
    Keywords
    ProxyAddresses
    PrimarySMTPAddress
    PrimarySMTPAddressPrefix
    PrimarySMTPAddressSuffix
    PrimaryX400Address
    PrimaryMSMailAddress
    PrimaryCCMailAddress
    PrimaryMacMailAddress
    PrimaryLotusNotesAddress
    PrimaryGroupWiseAddress
    EmailAddressPolicyEnabled
    Path
    DN
    CanonicalName
    CreationDate
    ModificationDate
    ParentContainer
    ParentContainerDN
    Name
    ClassName
    Type
    Guid
    Sid
    Description
    DisplayName
    OperationID
    OperationStatus
    Cache
    Connection
    DirectoryEntry

Now we go for everything:

Get-ADUser richard -Properties *
Get-QADUser richard -IncludeAllProperties | fl *

Get-ADUser richard -Properties *
Get-QADUser richard -IncludeAllProperties | fl *
AccountExpirationDate msExchPoliciesIncluded
accountExpires msExchMailboxSecurityDescriptor
AccountLockoutTime msDS-UserPasswordExpiryTimeComputed
AccountNotDelegated allowedAttributesEffective
adminCount msDS-ReplAttributeMetaData
AllowReversiblePasswordEncryption adminCount
BadLogonCount givenName
badPasswordTime mDBUseDefaults
badPwdCount msExchVersion
c tokenGroupsNoGCAcceptable
CannotChangePassword codePage
CanonicalName countryCode
Certificates sDRightsEffective
City legacyExchangeDN
CN instanceType
codePage whenChanged
Company modifyTimeStamp
Country structuralObjectClass
countryCode homeMTA
Created msDS-ReplValueMetaData
createTimeStamp uSNCreated
Deleted msExchHomeServerName
Department dSCorePropagationData
Description pwdLastSet
DisplayName uSNChanged
DistinguishedName whenCreated
Division l
DoesNotRequirePreAuth msDS-Approx-Immed-Subordinates
dSCorePropagationData distinguishedName
EmailAddress mailNickname
EmployeeID msExchRecipientTypeDetails
EmployeeNumber replPropertyMetaData
Enabled msDS-RevealedListBL
Fax msExchRecipientDisplayType
GivenName sAMAccountType
HomeDirectory servicePrincipalName
HomedirRequired badPwdCount
HomeDrive msExchMailboxGuid
homeMDB objectSid
homeMTA objectClass
HomePage allowedChildClasses
HomePhone tokenGroups
Initials msExchUserAccountControl
instanceType msDS-User-Account-Control-Computed
isDeleted cn
l objectGUID
LastBadPasswordAttempt protocolSettings
LastKnownParent badPasswordTime
lastLogon allowedAttributes
LastLogonDate msDS-KeyVersionNumber
lastLogonTimestamp fromEntry
legacyExchangeDN createTimeStamp
LockedOut lockoutTime
lockoutTime logonCount
logonCount mail
LogonWorkstations homeMDB
mail tokenGroupsGlobalAndUniversal
mailNickname objectCategory
Manager msDS-PrincipalName
mDBUseDefaults subSchemaSubEntry
MemberOf msExchUserCulture
MNSLogonAccount showInAddressBook
MobilePhone userAccountControl
Modified c
modifyTimeStamp nTSecurityDescriptor
msDS-User-Account-Control-Computed accountNameHistory
msExchHomeServerName aCSPolicyName
msExchMailboxGuid adminDescription
msExchMailboxSecurityDescriptor adminDisplayName
msExchPoliciesIncluded allowedChildClassesEffective
msExchRecipientDisplayType altRecipient
msExchRecipientTypeDetails altRecipientBL
msExchUserAccountControl altSecurityIdentities
msExchUserCulture assistant
msExchVersion attributeCertificate
Name attributeCertificateAttribute
nTSecurityDescriptor audio
ObjectCategory authOrig
ObjectClass authOrigBL
ObjectGUID autoReply
objectSid autoReplyMessage
Office bridgeheadServerListBL
OfficePhone businessCategory
Organization businessRoles
OtherName carLicense
PasswordExpired co
PasswordLastSet comment
PasswordNeverExpires controlAccessRights
PasswordNotRequired dBCSPwd
POBox defaultClassStore
PostalCode deletedItemFlags
PrimaryGroup delivContLength
primaryGroupID deliverAndRedirect
ProfilePath deliveryMechanism
ProtectedFromAccidentalDeletion delivExtContTypes
protocolSettings departmentNumber
proxyAddresses desktopProfile
pwdLastSet destinationIndicator
SamAccountName directReports
sAMAccountType displayNamePrintable
ScriptPath division
sDRightsEffective dLMemDefault
servicePrincipalName dLMemRejectPerms
ServicePrincipalNames dLMemRejectPermsBL
showInAddressBook dLMemSubmitPerms
SID dLMemSubmitPermsBL
SIDHistory dnQualifier
SmartcardLogonRequired dSASignature
State dynamicLDAPServer
StreetAddress employeeID
Surname employeeNumber
Title employeeType
TrustedForDelegation enabledProtocols
TrustedToAuthForDelegation expirationTime
UseDESKeyOnly extensionAttribute1
userAccountControl extensionAttribute10
userCertificate extensionAttribute11
UserPrincipalName extensionAttribute12
uSNChanged extensionAttribute13
uSNCreated extensionAttribute14
whenChanged extensionAttribute15
whenCreated extensionAttribute2
  extensionAttribute3
  extensionAttribute4
  extensionAttribute5
  extensionAttribute6
  extensionAttribute7
  extensionAttribute8
  extensionAttribute9
  extensionData
  extensionName
  facsimileTelephoneNumber
  flags
  folderPathname
  formData
  forwardingAddress
  frsComputerReferenceBL
  fRSMemberReferenceBL
  fSMORoleOwner
  garbageCollPeriod
  gecos
  generationQualifier
  gidNumber
  groupMembershipSAM
  groupPriority
  groupsToIgnore
  heuristics
  homePostalAddress
  houseIdentifier
  importedFrom
  info
  internationalISDNNumber
  internetEncoding
  ipPhone
  isCriticalSystemObject
  isDeleted
  isPrivilegeHolder
  isRecycled
  jpegPhoto
  kMServer
  labeledURI
  language
  languageCode
  lmPwdHistory
  localeID
  loginShell
  logonHours
  logonWorkstation
  managedObjects
  mAPIRecipient
  masteredBy
  maxStorage
  mDBOverHardQuotaLimit
  mDBOverQuotaLimit
  mDBStorageQuota
  mhsORAddress
  middleName
  mobile
  mS-DS-ConsistencyChildCount
  mS-DS-ConsistencyGuid
  mS-DS-CreatorSID
  msCOM-PartitionSetLink
  msCOM-UserLink
  msCOM-UserPartitionSetLink
  msDFSR-ComputerReferenceBL
  msDFSR-MemberReferenceBL
  msDRM-IdentityCertificate
  msDS-AllowedToDelegateTo
  msDS-AuthenticatedAtDC
  msDS-AuthenticatedToAccountlist
  msDS-Cached-Membership
  msDS-Cached-Membership-Time-Stamp
  msDS-EnabledFeatureBL
  msDS-FailedInteractiveLogonCount
  msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon
  msDS-HABSeniorityIndex
  msDS-HostServiceAccountBL
  msDS-IsDomainFor
  msDS-IsFullReplicaFor
  msDS-IsPartialReplicaFor
  msDS-KrbTgtLinkBl
  msDS-LastFailedInteractiveLogonTime
  msDS-LastKnownRDN
  msDS-LastSuccessfulInteractiveLogonTime
  msDS-LocalEffectiveDeletionTime
  msDS-LocalEffectiveRecycleTime
  msDs-masteredBy
  msDS-MembersForAzRoleBL
  msDS-NC-RO-Replica-Locations-BL
  msDS-NCReplCursors
  msDS-NCReplInboundNeighbors
  msDS-NCReplOutboundNeighbors
  msDS-NcType
  msDS-NonMembersBL
  msDS-ObjectReferenceBL
  msDS-OIDToGroupLinkBl
  msDS-OperationsForAzRoleBL
  msDS-OperationsForAzTaskBL
  msDS-PhoneticCompanyName
  msDS-PhoneticDepartment
  msDS-PhoneticDisplayName
  msDS-PhoneticFirstName
  msDS-PhoneticLastName
  msDS-PSOApplied
  msDS-ResultantPSO
  msDS-RevealedDSAs
  msDS-SecondaryKrbTgtNumber
  msDS-Site-Affinity
  msDS-SourceObjectDN
  msDS-SupportedEncryptionTypes
  msDS-TasksForAzRoleBL
  msDS-TasksForAzTaskBL
  msExchADCGlobalNames
  msExchAggregationSubscriptionCredential
  msExchALObjectVersion
  msExchAlternateMailboxes
  msExchApprovalApplicationLink
  msExchArbitrationMailbox
  msExchArchiveDatabaseBL
  msExchArchiveDatabaseLink
  msExchArchiveGUID
  msExchArchiveName
  msExchArchiveQuota
  msExchArchiveWarnQuota
  msExchAssistantName
  msExchAvailabilityOrgWideAccountBL
  msExchAvailabilityPerUserAccountBL
  msExchBlockedSendersHash
  msExchBypassModerationBL
  msExchBypassModerationFromDLMembersBL
  msExchBypassModerationFromDLMembersLink
  msExchBypassModerationLink
  msExchCalendarRepairDisabled
  msExchCoManagedObjectsBL
  msExchConferenceMailboxBL
  msExchConfigurationUnitBL
  msExchContentConversionSettings
  msExchControllingZone
  msExchCU
  msExchCustomProxyAddresses
  msExchDelegateListBL
  msExchDelegateListLink
  msExchDeviceAccessControlRuleBL
  msExchDirsyncID
  msExchDumpsterQuota
  msExchDumpsterWarningQuota
  msExchEdgeSyncCookies
  msExchEdgeSyncRetryCount
  msExchEdgeSyncSourceGuid
  msExchELCExpirySuspensionEnd
  msExchELCExpirySuspensionStart
  msExchELCMailboxFlags
  msExchEnableModeration
  msExchExpansionServerName
  msExchExternalOOFOptions
  msExchExternalSyncState
  msExchFBURL
  msExchForeignGroupSID
  msExchHABShowInDepartments
  msExchHideFromAddressLists
  msExchHouseIdentifier
  msExchIMACL
  msExchIMAddress
  msExchIMAP4Settings
  msExchIMAPOWAURLPrefixOverride
  msExchIMMetaPhysicalURL
  msExchImmutableId
  msExchIMPhysicalURL
  msExchIMVirtualServer
  msExchInconsistentState
  msExchIntendedMailboxPlanBL
  msExchIntendedMailboxPlanLink
  msExchLabeledURI
  msExchLicenseToken
  msExchMailboxFolderSet
  msExchMailboxMoveBatchName
  msExchMailboxMoveFlags
  msExchMailboxMoveRemoteHostName
  msExchMailboxMoveSourceMDBBL
  msExchMailboxMoveSourceMDBLink
  msExchMailboxMoveStatus
  msExchMailboxMoveTargetMDBBL
  msExchMailboxMoveTargetMDBLink
  msExchMailboxOABVirtualDirectoriesLink
  msExchMailboxPlanType
  msExchMailboxTemplateLink
  msExchMailboxUrl
  msExchManagementSettings
  msExchMasterAccountSid
  msExchMaxBlockedSenders
  msExchMaxSafeSenders
  msExchMDBRulesQuota
  msExchMessageHygieneFlags
  msExchMessageHygieneSCLDeleteThreshold
  msExchMessageHygieneSCLJunkThreshold
  msExchMessageHygieneSCLQuarantineThreshold
  msExchMessageHygieneSCLRejectThreshold
  msExchMobileAllowedDeviceIDs
  msExchMobileBlockedDeviceIDs
  msExchMobileDebugLogging
  msExchMobileMailboxFlags
  msExchMobileMailboxPolicyLink
  msExchMobileRemoteDocumentsAllowedServersBL
  msExchMobileRemoteDocumentsBlockedServersBL
  msExchMobileRemoteDocumentsInternalDomainSuffixListBL
  msExchMobileSettings
  msExchModeratedByLink
  msExchModeratedObjectsBL
  msExchModerationFlags
  msExchObjectCountQuota
  msExchObjectID
  msExchOmaAdminExtendedSettings
  msExchOmaAdminWirelessEnable
  msExchOrganizationsAddressBookRootsBL
  msExchOrganizationsGlobalAddressListsBL
  msExchOrganizationsTemplateRootsBL
  msExchOriginatingForest
  msExchOURoot
  msExchOWAAllowedFileTypesBL
  msExchOWAAllowedMimeTypesBL
  msExchOWABlockedFileTypesBL
  msExchOWABlockedMIMETypesBL
  msExchOWAForceSaveFileTypesBL
  msExchOWAForceSaveMIMETypesBL
  msExchOWAPolicy
  msExchOWARemoteDocumentsAllowedServersBL
  msExchOWARemoteDocumentsBlockedServersBL
  msExchOWARemoteDocumentsInternalDomainSuffixListBL
  msExchOWASettings
  msExchOWATranscodingFileTypesBL
  msExchOWATranscodingMimeTypesBL
  msExchParentPlanBL
  msExchParentPlanLink
  msExchPfRootUrl
  msExchPoliciesExcluded
  msExchPolicyEnabled
  msExchPolicyOptionList
  msExchPOP3Settings
  msExchPreviousAccountSid
  msExchPreviousHomeMDB
  msExchProvisioningFlags
  msExchProxyCustomProxy
  msExchQueryBaseDN
  msExchRBACPolicyBL
  msExchRBACPolicyLink
  msExchRecipientValidatorCookies
  msExchRecipLimit
  msExchRequireAuthToSendTo
  msExchResourceCapacity
  msExchResourceDisplay
  msExchResourceGUID
  msExchResourceMetaData
  msExchResourceProperties
  msExchResourceSearchProperties
  msExchRetentionComment
  msExchRetentionURL
  msExchRMSComputerAccountsBL
  msExchRMSComputerAccountsLink
  msExchSafeRecipientsHash
  msExchSafeSendersHash
  msExchSendAsAddresses
  msExchSenderHintTranslations
  msExchServerAssociationBL
  msExchServerAssociationLink
  msExchServerSiteBL
  msExchSetupStatus
  msExchSharingPartnerIdentities
  msExchSharingPolicyLink
  msExchSignupAddresses
  msExchSMTPReceiveDefaultAcceptedDomainBL
  msExchSupervisionDLBL
  msExchSupervisionDLLink
  msExchSupervisionOneOffBL
  msExchSupervisionOneOffLink
  msExchSupervisionUserBL
  msExchSupervisionUserLink
  msExchSyncAccountsPolicyDN
  msExchTextMessagingState
  msExchThrottlingPolicyDN
  msExchTransportInboundSettings
  msExchTransportOutboundSettings
  msExchTransportRecipientSettingsFlags
  msExchTUIPassword
  msExchTUISpeed
  msExchTUIVolume
  msExchUMAddresses
  msExchUMAudioCodec
  msExchUMAudioCodec2
  msExchUMCallingLineIDs
  msExchUMDtmfMap
  msExchUMEnabledFlags
  msExchUMEnabledFlags2
  msExchUMFaxId
  msExchUMListInDirectorySearch
  msExchUMMailboxOVALanguage
  msExchUMMaxGreetingDuration
  msExchUMOperatorNumber
  msExchUMPhoneProvider
  msExchUMPinChecksum
  msExchUMRecipientDialPlanLink
  msExchUMServerWritableFlags
  msExchUMSpokenName
  msExchUMTemplateLink
  msExchUnmergedAttsPt
  msExchUseOAB
  msExchUserBL
  msExchVoiceMailboxID
  msExchWindowsLiveID
  msIIS-FTPDir
  msIIS-FTPRoot
  mSMQDigests
  mSMQDigestsMig
  mSMQSignCertificates
  mSMQSignCertificatesMig
  msNPAllowDialin
  msNPCallingStationID
  msNPSavedCallingStationID
  msPKI-CredentialRoamingTokens
  msPKIAccountCredentials
  msPKIDPAPIMasterKeys
  msPKIRoamingTimeStamp
  msRADIUS-FramedInterfaceId
  msRADIUS-FramedIpv6Prefix
  msRADIUS-FramedIpv6Route
  msRADIUS-SavedFramedInterfaceId
  msRADIUS-SavedFramedIpv6Prefix
  msRADIUS-SavedFramedIpv6Route
  msRADIUSCallbackNumber
  msRADIUSFramedIPAddress
  msRADIUSFramedRoute
  msRADIUSServiceType
  msRASSavedCallbackNumber
  msRASSavedFramedIPAddress
  msRASSavedFramedRoute
  msSFU30Name
  msSFU30NisDomain
  msSFU30PosixMemberOf
  msTSAllowLogon
  msTSBrokenConnectionAction
  msTSConnectClientDrives
  msTSConnectPrinterDrives
  msTSDefaultToMainPrinter
  msTSExpireDate
  msTSExpireDate2
  msTSExpireDate3
  msTSExpireDate4
  msTSHomeDirectory
  msTSHomeDrive
  msTSInitialProgram
  msTSLicenseVersion
  msTSLicenseVersion2
  msTSLicenseVersion3
  msTSLicenseVersion4
  msTSLSProperty01
  msTSLSProperty02
  msTSManagingLS
  msTSManagingLS2
  msTSManagingLS3
  msTSManagingLS4
  msTSMaxConnectionTime
  msTSMaxDisconnectionTime
  msTSMaxIdleTime
  msTSPrimaryDesktop
  msTSProfilePath
  msTSProperty01
  msTSProperty02
  msTSReconnectionAction
  msTSRemoteControl
  msTSSecondaryDesktops
  msTSWorkDirectory
  netbootSCPBL
  networkAddress
  nonSecurityMemberBL
  ntPwdHistory
  o
  objectVersion
  operatorCount
  otherFacsimileTelephoneNumber
  otherHomePhone
  otherIpPhone
  otherLoginWorkstations
  otherMailbox
  otherMobile
  otherPager
  otherTelephone
  otherWellKnownObjects
  ou
  ownerBL
  partialAttributeDeletionList
  partialAttributeSet
  personalPager
  personalTitle
  photo
  physicalDeliveryOfficeName
  pOPCharacterSet
  pOPContentFormat
  possibleInferiors
  postalAddress
  preferredDeliveryMethod
  preferredLanguage
  preferredOU
  primaryInternationalISDNNumber
  primaryTelexNumber
  proxiedObjectName
  publicDelegates
  publicDelegatesBL
  queryPolicyBL
  registeredAddress
  replicatedObjectVersion
  replicationSensitivity
  replicationSignature
  replUpToDateVector
  repsFrom
  repsTo
  revision
  rid
  roomNumber
  scriptPath
  secretary
  securityIdentifier
  securityProtocol
  seeAlso
  serialNumber
  serverReferenceBL
  shadowExpire
  shadowFlag
  shadowInactive
  shadowLastChange
  shadowMax
  shadowMin
  shadowWarning
  showInAdvancedViewOnly
  sIDHistory
  siteObjectBL
  sn
  st
  street
  submissionContLength
  subRefs
  supplementalCredentials
  supportedAlgorithms
  systemFlags
  targetAddress
  telephoneAssistant
  telephoneNumber
  teletexTerminalIdentifier
  telexNumber
  terminalServer
  textEncodedORAddress
  thumbnailLogo
  thumbnailPhoto
  uid
  uidNumber
  unauthOrig
  unauthOrigBL
  unicodePwd
  unixHomeDirectory
  unixUserPassword
  unmergedAtts
  url
  userCert
  userCertificate
  userParameters
  userPassword
  userPKCS12
  userSharedFolder
  userSharedFolderOther
  userSMIMECertificate
  userWorkstations
  uSNDSALastObjRemoved
  USNIntersite
  uSNLastObjRem
  uSNSource
  versionNumber
  wbemPath
  wellKnownObjects
  wWWHomePage
  x121Address
  x500uniqueIdentifier
  City
  Company
  Department
  Email
  Fax
  FirstName
  HomePhone
  Initials
  LastName
  LogonName
  Manager
  MobilePhone
  Office
  Pager
  PhoneNumber
  PostalCode
  PostOfficeBox
  PrimaryGroupId
  StateOrProvince
  StreetAddress
  Title
  WebPage
  HomeDirectory
  HomeDrive
  ProfilePath
  LogonScript
  UserPrincipalName
  TsProfilePath
  TsHomeDirectory
  TsHomeDrive
  TsAllowLogon
  TsRemoteControl
  TsMaxDisconnectionTime
  TsMaxConnectionTime
  TsMaxIdleTime
  TsReconnectionAction
  TsBrokenConnectionAction
  TsConnectClientDrives
  TsConnectPrinterDrives
  TsDefaultToMainPrinter
  TsWorkDirectory
  TsInitialProgram
  AccountExpires
  PasswordLastSet
  PasswordAge
  PasswordExpires
  LastLogonTimestamp
  LastLogon
  LastLogoff
  AccountIsDisabled
  AccountIsLockedOut
  PasswordNeverExpires
  UserMustChangePassword
  AccountIsExpired
  PasswordIsExpired
  AccountExpirationStatus
  PasswordStatus
  DeprovisionStatus
  NTAccountName
  SamAccountName
  Security
  Domain
  LastKnownParent
  MemberOf
  NestedMemberOf
  Notes
  AllMemberOf
  Keywords
  ProxyAddresses
  PrimarySMTPAddress
  PrimarySMTPAddressPrefix
  PrimarySMTPAddressSuffix
  PrimaryX400Address
  PrimaryMSMailAddress
  PrimaryCCMailAddress
  PrimaryMacMailAddress
  PrimaryLotusNotesAddress
  PrimaryGroupWiseAddress
  EmailAddressPolicyEnabled
  Path
  DN
  CanonicalName
  CreationDate
  ModificationDate
  ParentContainer
  ParentContainerDN
  Name
  ClassName
  Type
  Guid
  Sid
  Description
  DisplayName
  OperationID
  OperationStatus
  Cache
  Connection
  DirectoryEntry

Also remember that because an attribute is given in the list it doesn’t mean that it will have a value!

UG meeting reminder - March 2012

Quick reminder that the UK user group meeting is on Tuesday 27 March @ 7.30 BST.  Details from

http://msmvps.com/blogs/richardsiddaway/archive/2012/03/06/uk-powershell-group-march-2012.aspx

 

The meeting is on the new CIM functionality in PowerShell v3.  This is a need to know technology as much of the new PowerShell functionality in Windows Server 8 is based on this.

Please double check the time as the UK switched to daylight saving time this weekend.

Updating AD users in bulk

A question was raised on the forums about bulk updated of user information.  This is an example of how to handle it

A CSV file was created

Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" | Format-Table –AutoSize

 

userid JobTitle  Cost Center HireDate      
------ --------  ----------- --------      
usera  JobTitleA 1001001     1 January 2011
userb  JobTitleB 1001002     1 February 2011
userc  JobTitleC 1001003     1 March 2011  
userd  JobTitleD 1001004     1 April 2011  

The task is to use the userids to add the data into extensionAttribute3, extensionAttribute4, and extensionAttribute5

Using the Microsoft cmdlets – read the csv file and for each object (row) use Set-ADuser to set the appropriate values.

The results can be displayed using Get-ADuser – note we need the Properties parameter

If required we can clear those attributes using the –Clear parameter on Set-ADUser

Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
  Set-ADUser -Identity $($_.userid) -Replace @{extensionAttribute3 = $($_.JobTitle); `
extensionAttribute4 = $($_."Cost Center"); extensionAttribute5  = $($_.HireDate)}            
}            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 Get-ADUser -Identity $($_.userid) -Properties * | select samaccountname, extensionAttribute3, extensionAttribute4, extensionAttribute5            
}            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 Set-ADUser -Identity $($_.userid) -Clear extensionAttribute3, extensionAttribute4, extensionAttribute5            
}

The Quest cmdlets are similar

Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
  Set-QADUser -Identity $($_.userid) -ObjectAttributes @{extensionAttribute3 = $($_.JobTitle); `
    extensionAttribute4 = $($_."Cost Center"); extensionAttribute5  = $($_.HireDate)}            
}            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 Get-QADUser -Identity $($_.userid) -IncludeAllProperties | 
select samaccountname, extensionAttribute3, extensionAttribute4, extensionAttribute5            
}            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 Set-QADUser -Identity $($_.userid) -ObjectAttributes @{extensionAttribute3 = ""; `
extensionAttribute4 = ""; extensionAttribute5  = ""}            
}

Use  -ObjectAttributes instead of –Replace.  We don’t have a –Clear parameter so need to set the values to empty

Scripting involves  a bit more work

Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 $data = $_            
 $root = [ADSI]""            
 $search = [adsisearcher]$root            
 $search.Filter = "(&(objectclass=user)(objectcategory=user)(samaccountname=$($data.userid)))"             
 $search.SizeLimit = 3000            
 $search.FindOne() | foreach {            
             
 $user = $_.GetDirectoryEntry()            
 $user.extensionAttribute3 = $($data.JobTitle)            
 $user.extensionAttribute4 = $($data."Cost Center")            
 $user.extensionAttribute5 = $($data.HireDate)            
 $user.SetInfo()            
}            
              
}            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 $data = $_            
 $root = [ADSI]""            
 $search = [adsisearcher]$root            
 $search.Filter = "(&(objectclass=user)(objectcategory=user)(samaccountname=$($data.userid)))"             
 $search.SizeLimit = 3000            
 $search.FindOne() | foreach {            
  $user = $_.GetDirectoryEntry()            
  $user | select  @{N="samaccountname"; E={$_.samaccountname}},            
  @{N="extensionAttribute3"; E={$_.extensionAttribute3}},            
  @{N="extensionAttribute4"; E={$_.extensionAttribute4}},            
  @{N="extensionAttribute5"; E={$_.extensionAttribute5}}            
 }            
}            
            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 $data = $_            
 $root = [ADSI]""            
 $search = [adsisearcher]$root            
 $search.Filter = "(&(objectclass=user)(objectcategory=user)(samaccountname=$($data.userid)))"             
 $search.SizeLimit = 3000            
 $search.FindOne() | foreach {            
             
 $user = $_.GetDirectoryEntry()            
 $user.extensionAttribute3 = " "            
 $user.extensionAttribute4 = " "            
 $user.extensionAttribute5 = " "            
 $user.SetInfo()            
}            
}

Use [adsisearcher] to find the acccount – get a directory entry and set the values. The display is similar except we select the attributes. Clearing the attributes involves setting it to a blank string

Finally the provider

Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 $data = $_            
 Get-ChildItem -Filter "(&(objectclass=user)(objectcategory=user)(samaccountname=$($data.userid)))"  `
 -Path Ad:\"DC=Manticore,DC=org" -Recurse |             
 foreach {             
 Set-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute3 -Value $($data.JobTitle)            
 Set-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute4 -Value $($data."Cost Center")            
 Set-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute5 -Value $($data.HireDate)            
}             
}            
            
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 $data = $_            
 Get-ChildItem -Filter "(&(objectclass=user)(objectcategory=user)(samaccountname=$($data.userid)))"  `
 -Path Ad:\"DC=Manticore,DC=org" -Recurse |             
 foreach {             
  New-Object -TypeName PSObject -Property @{            
  samaccountname = Get-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name samaccountname | 
select -ExpandProperty samaccountname            
  extensionAttribute3 = Get-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute3 | 
select -ExpandProperty extensionAttribute3            
  extensionAttribute4 = Get-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute4 | 
select -ExpandProperty extensionAttribute4            
  extensionAttribute5 = Get-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute5 | 
select -ExpandProperty extensionAttribute5            
 }            
}             
}              
            
Import-Csv -Path "C:\Scripts\AD Examples\Users\bulkchangetest.csv" |            
foreach {            
 $data = $_            
 Get-ChildItem -Filter "(&(objectclass=user)(objectcategory=user)(samaccountname=$($data.userid)))"  `
 -Path Ad:\"DC=Manticore,DC=org" -Recurse |             
 foreach {             
 Set-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute3 -Value " "            
 Set-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute4 -Value " "            
 Set-ItemProperty -Path Ad:\"$($_.DistinguishedName)" -Name extensionAttribute5 -Value " "            
}             
}

We can search for the user with an LDAP filter as we did with the script – then use Set-ItemProperty to set the values. Displaying the values is the same except we use Get-Itemproperty and the final clear is the same as the original set except we set the values to a blank string

PowerShell Deep Dive 2012 speaking

I heard at the beginning of the week that I’ve been granted a speaker slot at the PowerShell Deep Dive next month - http://www.theexpertsconference.com/us/2012/

I’ll be speaking on creating cmdlets from WMI objects using a new feature in PowerShell v3 that is so cool it could start a new Ice Age

Look forward to seeing you there

Posted by RichardSiddaway | with no comments
Filed under: ,

Folder sizes

Question on the forums related to folder sizes and last write time

Get-ChildItem -Path "C:\PersonalData\MyBooks\PowerShell and WMI" -Recurse |             
where { $_.PSIsContainer} |            
foreach {            
 $size = Get-ChildItem -Path $_.FullName | measure -Sum Length | select -ExpandProperty Sum            
             
 Add-Member -InputObject $($_) -MemberType NoteProperty -Name Size -Value $size            
            
 $_ | select Fullname, LastWriteTime, @{N="Size(MB)"; E={[math]::Round(($_.Size/1mb), 2)}}            
} | Format-Table -AutoSize -Wrap

Unfortunately the object returned by get-ChildItem doesn’t include folder size. So we loop through each folder & get the sum of its contents. The size value is added to the folder object and Fullname, LastwriteTime and size displayed.  The size is recalculated to megabytes. Substitute your favourite size

Posted by RichardSiddaway | with no comments
Filed under:

Deleted user accounts–correction

In the last post which looked at finding user accounts that had been deleted I had this syntax for the Microsoft cmdlets

Get-ADObject -Filter {isDeleted -eq $true -and name -ne "Deleted Objects" } -IncludeDeletedObjects |
Format-List Name, Distinguishedname
 

This had a mistake that I missed. It will return all deleted objects.  The syntax should be

Get-ADObject -Filter {objectclass -eq "user" -and isDeleted -eq $true -and name -ne "Deleted Objects" } -IncludeDeletedObjects |
Format-List Name, Distinguishedname
 

Adding

objectclass -eq "user"

to the filter ensures that we only get deleted user objects

Deleted user accounts

User accounts get deleted – sometimes on purpose and sometimes its more of a…  oops

You can find accounts that have been deleted like this

            
"`nMicrosoft"            
Get-ADObject -Filter {isDeleted -eq $true -and name -ne "Deleted Objects" } -IncludeDeletedObjects |             
Format-List Name, Distinguishedname             
             
"`nQuest"            
Get-QADUser -Tombstone -SizeLimit 3000 |            
Format-Table Name, DN -AutoSize            
            
"`nScript"            
$data = @()            
[ADSISEARCHER]$search = "(&(isDeleted=TRUE)(objectclass=user))"            
$search.tombstone = $true            
$results = $search.Findall()            
            
foreach ($result in $results){            
   $data += $result.Properties |             
    select @{N="Name"; E={$_.name}}, @{N="DistinguishedName"; E={$_.distinguishedname}}            
}             
$data | Format-List

The provider doesn’t seem to supply this functionality – I can’t find a way to tell it to include deleted items. The cmdlets have parameters for this and the script allows us to use $search.tombstone = $true

We can then display the Name and Distinguishedname which look like this

Name              : LASTNAME,Firstname
                    DEL:02f81cc2-0cea-418b-8bb7-2b15f33a69c2
DistinguishedName : CN=LASTNAME\,Firstname\0ADEL:02f81cc2-0cea-418b-8bb7-2b15f33a69c2,CN=Deleted Obj
                    ects,DC=Manticore,DC=org

 

Now we know whats been deleted what can we do with it

Reading registry values with CIM

In this post

http://msmvps.com/blogs/richardsiddaway/archive/2012/03/10/migrating-to-cim-doh.aspx

and its predecessors we saw how to enumerate registry sub-keys. But how do we read a registry value?

function get-CIMRegValue{             
[CmdletBinding(DefaultParameterSetName="UseComputer")]             
            
param (             
 [parameter(Mandatory=$true)]            
 [ValidateSet("HKCR", "HKCU", "HKLM", "HKUS", "HKCC")]            
 [string]$hive,            
            
 [parameter(Mandatory=$true)]            
 [string]$key,            
            
 [parameter(Mandatory=$true)]            
 [string]$value,            
            
 [parameter(Mandatory=$true)]            
 [string]            
 [Validateset("DWORD", "EXPANDSZ", "MULTISZ", "QWORD", "SZ")]            
 $type,            
            
  [parameter(ValueFromPipeline=$true,            
   ValueFromPipelineByPropertyName=$true)]            
 [parameter(ParameterSetName="UseComputer")]             
 [string]$computer="$env:COMPUTERNAME",            
             
 [parameter(ValueFromPipeline=$true,            
   ValueFromPipelineByPropertyName=$true)]            
 [parameter(ParameterSetName="UseCIMSession")]             
 [Microsoft.Management.Infrastructure.CimSession]$cimsession            
             
)             
BEGIN{}#begin             
PROCESS{            
            
switch ($hive){            
"HKCR" { [uint32]$hdkey = 2147483648} #HKEY_CLASSES_ROOT            
"HKCU" { [uint32]$hdkey = 2147483649} #HKEY_CURRENT_USER            
"HKLM" { [uint32]$hdkey = 2147483650} #HKEY_LOCAL_MACHINE            
"HKUS" { [uint32]$hdkey = 2147483651} #HKEY_USERS            
"HKCC" { [uint32]$hdkey = 2147483653} #HKEY_CURRENT_CONFIG            
}            
            
switch ($type) {            
"DWORD"     {$methodname = "GetDwordValue"}            
"EXPANDSZ"  {$methodname = "GetExpandedStringValue"}            
"MULTISZ"   {$methodname = "GetMultiStringValue"}            
"QWORD"     {$methodname = "GetQwordValue"}            
"SZ"        {$methodname = "GetStringValue"}            
}            
$arglist = @{hDefKey = $hdkey; sSubKeyName = $key; sValueName = $value}            
            
switch ($psCmdlet.ParameterSetName) {            
 "UseComputer"    {$result = Invoke-CimMethod -Namespace "root\cimv2" -ClassName StdRegProv -MethodName $methodname  -Arguments $arglist -ComputerName $computer}            
 "UseCIMSession"  {$result = Invoke-CimMethod -Namespace "root\cimv2" -ClassName StdRegProv -MethodName $methodname  -Arguments $arglist -CimSession $cimsession }            
 default {Write-Host "Error!!! Should not be here" }            
}            
            
switch ($type) {            
"DWORD"     {$result | select -ExpandProperty uValue}            
"EXPANDSZ"  {$result | select -ExpandProperty sValue}            
"MULTISZ"   {$result | select -ExpandProperty sValue}            
"QWORD"     {$result | select -ExpandProperty uValue}            
"SZ"        {$result | select -ExpandProperty sValue}            
}            
             
}#process             
END{}#end            
            
<# 
.SYNOPSIS
Displays a registry value

.DESCRIPTION
Displays a registry value using WSMAN or DCOM 
to access remote machines 

.PARAMETER  hive
Hive Name. One of "HKCR", "HKCU", "HKLM", "HKUS" or "HKCC"
The name is validated against the set

.PARAMETER  key
The registry key - without the hive name e.g.
"SYSTEM\CurrentControlSet\Services\BITS"

.PARAMETER value
The specific registry value to return for the 
given key

.PARAMETER  type
The type of registry value to return.
Must be one of
"DWORD", "EXPANDSZ", "MULTISZ", "QWORD", "SZ"

.PARAMETER  computer
Name of a remote computer. Connectivity will be by WSMAN.

.PARAMETER  cimsession
An object representing a cimsession. Connectivity is controlled 
by the CIM session and can be WSMAN or DCOM

.EXAMPLE                                                                                       
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value DelayedAutoStart -type DWORD

.EXAMPLE
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value ObjectName -type SZ  

.EXAMPLE
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value DependOnService -type MULTISZ 

.EXAMPLE
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value ImagePath -type EXPANDSZ

.EXAMPLE
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value DelayedAutoStart -type DWORD -computer "."

.EXAMPLE
$cs = New-CimSession -ComputerName Win7test  
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value DelayedAutoStart -type DWORD -cimsession $cs   

.EXAMPLE
$opt = New-CimSessionOption -Protocol Dcom                                                                                                          
$csd = New-CimSession -ComputerName server02 -SessionOption $opt                                                                                    
get-CIMRegValue -hive HKLM -key "SYSTEM\CurrentControlSet\services\BITS" -value DelayedAutoStart -type DWORD -cimsession $csd

.NOTES


.LINK

#>            
            
}

Parameters define the hive, key, value to be read and the type of value.

Registry values come in a number of types:

  • DWORD and QWORD are 32 & 64 bit numbers
  • SZ is a string
  • EXPANDSZ is a string containing environmental variables that gets expanded
  • MULTISZ is a multi-valued string

Parameters to define a computer name or CIM Session are also present

The numeric value for the hive is set in a switch statement. The data type is used to define the method name – each data type has its own method.

The argument list is populated and the method is invoked using a computer name or CIM session as appropriate

The results are decoded according to type.

Full help is provided on the function.

Counting the members of a group

The need for a particular group comes and goes and eventually the group isn’t needed anymore. At that time you have to delete the group but how do you know a group isn’t needed? Probably because its empty and how do you know its empty?

## counts the members of all groups            
##  displays by number of members            
            
"`nMicrosoft"            
$data = @()            
Get-ADGroup -Filter * |             
foreach {            
 $count = (Get-ADGroupMember -Identity $($_.DistinguishedName)).Count            
 if ($count -eq $null){$count = 0}            
 $data += New-Object -TypeName PSObject -Property @{            
   Name = $($_.Name)            
   DistinguishedName = $($_.DistinguishedName)            
   MemberCount = $count            
 }             
}            
$data | sort MemberCount -Descending | Format-Table -AutoSize            
            
"`nAD provider"            
$data = @()            
Get-ChildItem -Filter "(objectclass=group)" -Path Ad:\"DC=Manticore,DC=org" -Recurse |            
foreach {             
  $group = [adsi]"LDAP://$($_.DistinguishedName)"            
                
  $count = ($group.Member).Count            
  if ($count -eq $null){$count = 0}            
  $data += New-Object -TypeName PSObject -Property @{            
    Name = $($group.Name)            
    DistinguishedName = $($group.distinguishedName)            
    MemberCount = $count            
  }            
}            
$data | sort MemberCount -Descending | Format-Table -AutoSize            
            
"`nQuest"            
$data = @()            
Get-QADGroup |             
foreach {            
 $count = (Get-QADGroupMember -Identity $($_.DN)).Count            
 if ($count -eq $null){$count = 0}            
 $data += New-Object -TypeName PSObject -Property @{            
   Name = $($_.Name)            
   DistinguishedName = $($_.DN)            
   MemberCount = $count            
 }             
}            
$data | sort MemberCount -Descending | Format-Table -AutoSize            
            
            
"`nScript"            
$data = @()            
$root = [ADSI]""            
$search = [adsisearcher]$root            
$search.Filter = "(objectclass=group)"            
$search.SizeLimit = 3000            
$search.FindAll() |            
foreach {            
 $group = $_.GetDirectoryEntry()              
             
 $count = ($group.Member).Count            
 if ($count -eq $null){$count = 0}            
 $data += New-Object -TypeName PSObject -Property @{            
   Name = $($group.Name)            
   DistinguishedName = $($group.distinguishedName)            
   MemberCount = $count            
}            
}            
$data | sort MemberCount -Descending | Format-Table -AutoSize            

 

Conceptually all of the solutions are the same – find all the groups in the domain, and count the number of members. The cmdlet solutions are similar as are the script and the provider.

In my testing the script and provider were much faster than the cmdlets

Domain controllers and Global catalogs in the current site

This little script kills two birds with one stone. Which is great unless you happen to be a little bird.

We can use this to discover the domain controllers, and which of them are global catalogs, in the current site

$site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite()            
$site.Servers | select Name, Domain, @{Label="GC";Expression={$_.IsGlobalCatalog()}}

Use the ActiveDirectorySite class’ GetComputerSite method. Pipe the collection of servers and select the name and domain. The IsGlobalCatalog() method on the domain controller object is used to determine if it is a global catalog

Get Global Catalog from DNS

One option for finding global catalog servers is often overlooked – DNS.  In an AD environment DNS stores the SRV records that advertise the services domain controllers can deliver

$dnsserver = "dc02"            
Get-WmiObject -Namespace 'root\MicrosoftDNS' -Class  MicrosoftDNS_SRVType `
-ComputerName $dnsserver -Filter "ContainerName = 'Manticore.org'" |             
Where {$_.OwnerName -like "_gc*"} |            
select TextRepresentation

We are interested in the ‘root\MicrosoftDNS’ name space and the MicrosoftDNS_SRVType records. We want the manticore.org zone and all records where the Ownername is like “_gc*”

The results look like this

_gc._tcp.Site1._sites.Manticore.org IN SRV 0 100 3268 dc02.manticore.org.
_gc._tcp.Site1._sites.Manticore.org IN SRV 0 100 3268 server02.manticore.org.  
_gc._tcp.Manticore.org IN SRV 0 100 3268 dc02.manticore.org.  
_gc._tcp.Manticore.org IN SRV 0 100 3268 server02.manticore.org. 

Disable Global catalog

Of course once you’ve learned how to enable something you need to know how to disable

$dc = "dc02.manticore.org"            
$contextType = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]::DirectoryServer            
$context = New-Object -TypeName System.DirectoryServices.ActiveDirectory.DirectoryContext -ArgumentList $contextType, $dc            
$gc = [System.DirectoryServices.ActiveDirectory.GlobalCatalog]::GetGlobalCatalog($context)            
$gc.DisableGlobalCatalog()

Similar to enabling but this time we create a GlobalCatalog object and use the DisableGlobalCatalog() method

Enable Global catalog

Enabling a domain controller is simple through the GUI however its just even easier with PowerShell

$dc = "dc02.manticore.org"            
$contextType = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]::DirectoryServer            
$context = New-Object -TypeName System.DirectoryServices.ActiveDirectory.DirectoryContext -ArgumentList $contextType, $dc            
$gc = [System.DirectoryServices.ActiveDirectory.DomainController]::GetDomainController($context)            
$gc.EnableGlobalCatalog()

Create a context type of Directory Server. Create a context of that type for the domain controller to be promoted. Get the domain controller as a System.DirectoryServices.ActiveDirectory.DomainController object and call the EnableGlobalCatalog() method.

There is an alternative using ADSI but I think this is simpler. Put it in a function with the domain controller name as a parameter and its good to go.

Finding Global Catalog servers in the forest

Global catalogs are domain controllers that also hold a subset of information on all objects in the forest. They are a required infrastructure component for Universal Groups and Exchange among other things.

            
"`nMicrosoft"            
Get-ADForest |             
select -ExpandProperty GlobalCatalogs |            
Format-Table            
            
"`nScript"            
$for = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()            
$for.FindAllGlobalCatalogs() |             
select Name, IPAddress |             
Format-table

Only two options for discovering them. The Microsoft cmdlets provide a Get-ADForest that returns an object representing the forest – it includes a collection of global catalog names

The Script uses System.DirectoryServices.ActiveDirectory.Forest and the GetCurrentForest() method to discover the forest object and the collection of global catalogs.

There doesn’t seem to be an easy way to do the job through the provider or the Quest cmdlets

Move a single FSMO role

Sometimes you just want to move a single FSMO role

 

function move-afsmo {            
[CmdletBinding()]            
param([string]$server,             
            
[ValidateSet("schema", "domain", "rid", "infra", "pdc")]            
[string]$fsmo            
)            
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()            
$sid = ($dom.GetDirectoryEntry()).objectSid            
$dc = [ADSI]"LDAP://$server/rootDSE"            
            
switch ($fsmo.ToLower()){            
    "schema" {$role = "becomeSchemaMaster"; break}            
    "domain" {$role = "becomeDomainMaster"; break}            
    "rid"    {$role = "becomeRidMaster"; break}            
    "infra"  {$role = "becomeInfraStructureMaster"; break}            
    "pdc"    {$role = "becomePDC"; break}            
}            
            
if ($role -eq "becomePDC"){ $dc.Put($role, $sid[0])}            
else {$dc.Put($role, 1) }            
$dc.SetInfo()            
}

 

This function takes a domain controller name and a role and performs the transfer.

move-afsmo -server dc02 -fsmo schema                                       
move-afsmo -server dc02 -fsmo domain                                       
move-afsmo -server dc02 -fsmo rid                                          
move-afsmo -server dc02 -fsmo infra                                        
move-afsmo -server dc02 -fsmo pdc 

The roles are validated on input to determine the given value is in the set of roles. A switch statement sets the role to input to the Put() method. The transfer is performed as previously

Move all fsmo roles

When AD is first installed all of the FSMO roles are placed on the first domain controller in the forest. If you want to move all of the FSMO roles

$server = "server02"            
            
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()            
$sid = ($dom.GetDirectoryEntry()).objectSid            
$dc = [ADSI]"LDAP://$server/rootDSE"            
            
$fsmo = "becomeSchemaMaster", "becomeDomainMaster", "becomeRidMaster", "becomeInfraStructureMaster", "becomePDC"            
foreach ($role in $fsmo){             
    if ($role -eq "becomePDC"){ $dc.Put($role, $sid[0])}            
    else {$dc.Put($role, 1) }            
    $dc.SetInfo()            
}

Select the server that you want to move them to. Get the domain SID (needed for moving the PDC emulator role) and a directory entry for the target DC.

Loop through the fsmo roles and trigger the change.

There isn’t an easy way to do this with the provider or the cmdlets.

There is a method on the System.DirectoryServices.ActiveDirectory.DomainController class called TransferRoleOwnership. It doesn’t fully work with Windows 2008 and above and I would recommend against its use

Up coming User group sessions

The sessions for the next few months are:

  • 27 March – PowerShell v3 CIM cmdlets and “cmlets over objects”
  • April – Managing Windows Server 8 with PowerShell
  • May – Managing Windows Server 8 with PowerShell

No thats not a mistake – there is so much new PowerShell functionality in Windows server 8 that two sessions will just scratch the surface.  I’m delivering the April session and PowerShell MVP Jonathan Medd is delivering the May session.

Details on March’s sessions from

http://msmvps.com/blogs/richardsiddaway/archive/2012/03/06/uk-powershell-group-march-2012.aspx

As always the session will be recorded and made available afterwards.

More Posts Next page »