Quick-Hits Friday: The Scripting Guys Respond to a Bunch of Questions (9/24/10)

Quick-Hits Friday: The Scripting Guys Respond to a Bunch of Questions (9/24/10)

  • Comments 1
  • Likes


In this post:

 

 Shuffling Values Around in an Active Directory Organizational Unit

Hey, Scripting Guy! Question

 

Hey, Scripting Guy! I need to shuffle values around in one organizational unit (OU) in Active Directory. I have a bunch of users with a field populated (in my case, “Office”), and that value needs to be moved to another field (in my case, “ExtensionAttribute15”).  I was hoping to point the script at an OU and have it traverse the entire OU, copying the value for each user, and then setting the original field (“Office”) to NULL. I have been experimenting with Windows PowerShell and VBScript, but both seem to want to export the users to a file and then import them again (there are a few thousand users in this OU, so that file may get a bit unruly). Is there any way I could script this?

-- MH

 

 

Hey, Scripting Guy! Answer Hello MH,

 

Yes, this can be done. As seen in the following image, extensionattribute14 is an attribute that exists on an object in Active Directory. 

If you have one domain controller that is running Windows Server 2008 R2, you can use the Active Directory cmdlets to query the organizational unit, and then to make your changes. Take a look at the first two posts on this page. They show how to query Active Directory using the Windows Server 2008 R2 cmdlets. The remaining articles show querying AD using ADO, and the directory searcher object, a technique you may need to use if you do not have the Windows Server 2008 R2 cmdlets available to you.

If you choose to use VBScript, you will still need to query Active Directory. In this situation, you will use ADO. It can become a bit complicated, so you should take a look at these Hey, Scripting Guy! posts. After you have queried the AD OU, for the users, you make your changes inside the loop.

Here is a script I wrote to search for a missing attribute.

# -----------------------------------------------------------------------------
#
# SearchAdForMissingAttributeValue.ps1
# Ed Wilson, MSFT, 11/1/2008
#
# Uses the adsiSearcher type accelerator to search ad
# uses findall method to return values
# uses an LDAP dialect type of search syntax
# uses the -begin, -process and -end parameters of the foreach-object cmdlet
# this allows pre-processing to display a head for the output, and the process
# obtains the data, and then end displays our summary text.
# This is one cmdlet, and therefore we need to use the ` for line continuation
#
# -----------------------------------------------------------------------------

#Requires -version 2.0
$SearchAttribute = "HomeDirectory"
$DisplayAttribute = "DistinguishedName"
$SearchRoot = "ou=testou,dc=nwtraders,dc=com"
$filter = "ObjectCategory=user"
$ds = [adsiSearcher]$filter
$ds.SearchRoot = "LDAP://$SearchRoot"
$ds.findAll() |
ForEach-Object `
  -BEGIN { $i = 0 ; "$filter missing $SearchAttribute value" } `
  -PROCESS `
   {
     IF([string]::isNullOrEmpty($_.properties.item($SearchAttribute)))
      {
       $_.Properties.item($DisplayAttribute)
       $i++
      } # end if
   } `
  -END { "There are $i missing the $SearchAttribute value" }


Inside the Process section, the IF statement is used to find the attribute. Inside the script block ({ }) is the action you need to perform. You would here set the property value to $null.

 

 

 How Can I Be Notified by Email of Specific Words Being Found in the Event Log? 

Hey, Scripting Guy! Question

 

Hey, Scripting Guy!  This script from a few years ago works great. I love the way it monitors event log entries for specific words. I was wondering how to add an email notification to it as well. I do not know how to script, but I love your webcasts on scripting. Here is my Frankenstein version of how I think the email should be sent when I monitor this event. Thank you in advance!

strComputer = "myserver"

Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
        strComputer & "\root\cimv2")

Set colEvents = objWMIService.ExecNotificationQuery _   
    ("Select * From __InstanceCreationEvent Where " _
        & "TargetInstance isa 'Win32_NTLogEvent'")

Do
    Set objEvent = colEvents.NextEvent
    If InStr((objEvent.TargetInstance.EventCode), "1111") Then
        Wscript.Echo Now
        Wscript.Echo "Category: " & objEvent.TargetInstance.Category
        Wscript.Echo "Event Code: " & objEvent.TargetInstance.EventCode
        Wscript.Echo "Message: " & objEvent.TargetInstance.Message
        Wscript.Echo "Record Number: " & objEvent.TargetInstance.RecordNumber
        Wscript.Echo "Source Name: " & objEvent.TargetInstance.SourceName
        Wscript.Echo "Event Type: " & objEvent.TargetInstance.Type
        Wscript.Echo
    End If
Loop

Set objEmail = CreateObject("CDO.Message")

objEmail.From = "johndoe@northwind.com"
objEmail.To = "janedoe@northwind.com"
objEmail.Subject = "Event-Log 1111"
objEmail.Textbody = "Event ID 1111 has been triggered."
objEmail.Send

-- MS

 

 

Hey, Scripting Guy! Answer Hello MS,

 

I would try something like this. I moved the code that sends the email to a function that I called SendMain. This makes the script a bit easier to read, and also makes it easier to call the code that sends the email.

MonitorEventLogSendEmail.vbs

Sub SendMain
Set objEmail = CreateObject("CDO.Message")

objEmail.From = "johndoe@northwind.com"
objEmail.To = "janedoe@northwind.com"
objEmail.Subject = "Event-Log 1111"
objEmail.Textbody = "Event ID 1111 has been triggered."
objEmail.Send
END SUB

strComputer = "myserver"

Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
        strComputer & "\root\cimv2")

Set colEvents = objWMIService.ExecNotificationQuery _   
    ("Select * From __InstanceCreationEvent Where " _
        & "TargetInstance isa 'Win32_NTLogEvent'")

Do
    Set objEvent = colEvents.NextEvent
    If InStr((objEvent.TargetInstance.EventCode), "1111") Then
        Wscript.Echo Now
        Wscript.Echo "Category: " & objEvent.TargetInstance.Category
        Wscript.Echo "Event Code: " & objEvent.TargetInstance.EventCode
        Wscript.Echo "Message: " & objEvent.TargetInstance.Message
        Wscript.Echo "Record Number: " & objEvent.TargetInstance.RecordNumber
        Wscript.Echo "Source Name: " & objEvent.TargetInstance.SourceName
        Wscript.Echo "Event Type: " & objEvent.TargetInstance.Type
        Wscript.Echo
SendMail
    End If
Loop

 

Well, this concludes another edition of Quick-Hits Friday. Join us tomorrow for Weekend Scripter.

We would love you to follow us on Twitter and Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys


 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment