Add system name to Active Directory OU before deployment


#1

I have the need to pre-populate a system name in a specific OU before I an join the system to my Windows domain. Does anyone have an example Ruby script that can do this?


#2

Hi,

I don’t have automate scripts ready out of the box.
However, I’ve already done some dirty trials in ruby to manipulate ldap objects. It might help you getting your script up & running.

#!/usr/bin/ruby
require 'rubygems'
require 'net/ldap'

#Connection string
ldap = Net::LDAP.new
ldap.host = 'ldap-server.fqdn'
ldap.port = 389 #NonSecure LDAP
ldap.auth "user@fqdn", "password"

#Input server name
puts "Type in computer name:"
servername = gets.strip

#Create server in the correct ou
ou = "Servers"
dn = "cn=#{servername}, OU=#{ou}, DC=LAB, DC=LOCAL"
puts dn
attr = {
            :cn => servername,
            :objectclass => ["computer"],
            :sAMAccountName => "#{servername}$",
            :userAccountControl => '4130'
            }
ldap.add(:dn => dn, :attributes => attr)
puts ldap.get_operation_result.message

#Add new server into groups
groupDn = 'CN=WindowsServers,OU=GROUPES,DC=LAB,DC=LOCAL'
ldap.add_attribute groupDn, :member, dn
p ldap.get_operation_result.message

#Remove group members (remove all members)
ldap.delete_attribute groupDn, :member
p ldap.get_operation_result.message

#Search for the server created in LDAP and show count
filter = Net::LDAP::Filter.eq( "cn", "#{servername}" )
treebase = "dc=lab,dc=local"

p ldap.search( :base => treebase, :filter => filter ).count

#Finally delete object created
ldap.delete :dn => dn
p ldap.get_operation_result.message

#Search engine
=begin
filter = Net::LDAP::Filter.eq( "cn", "#{servername}" )
treebase = "dc=lab,dc=local"
ldap.search( :base => treebase, :filter => filter ) do |entry|
  puts "DN: #{entry.dn}"
  entry.each do |attribute, values|
    puts "   #{attribute}:"
    values.each do |value|
      puts "      --->#{value}"
    end
  end
end
=end

Regards,
Joseph.


#3

I got a hold of some similar code. Might be helpful to triangulate.

###################################
#
# CFME Automate Method: NeTLDAP_AddComputer
#
# Author: Kevin Morey 
#
# Notes: This method is will create a computer in Active Directory
#  - gem requirements net/ldap
#  - vmdb_object_type: $evm.root['vm']
#
###################################
begin
  # Method for logging
  def log(level, message)
    @method = 'NeTLDAP_AddComputer'
    $evm.log(level, "#{@method} - #{message}")
  end

  # dump_root
  def dump_root()
    log(:info, "Root:<$evm.root> Begin $evm.root.attributes")
    $evm.root.attributes.sort.each { |k, v| log(:info, "Root:<$evm.root> Attribute - #{k}: #{v}")}
    log(:info, "Root:<$evm.root> End $evm.root.attributes")
    log(:info, "")
  end

  # call_ldap
  def call_ldap(vm)
    require 'rubygems'
    require 'net/ldap'

    # get parameters 
    servername = nil || $evm.object['servername']
    username = nil || $evm.object['username']
    password = nil || $evm.object.decrypt('password')
    basedn = nil || $evm.object['basedn']
    ou = "ou=CloudForms, #{basedn}"
    dn = "cn=#{vm.name}, #{ou}"

    # setup authentication to LDAP
    ldap = Net::LDAP.new :host => servername,
      :port => 389,
    :auth => {
      :method => :simple,
      :username => "cn=#{username}, cn=users, #{basedn}",
      :password => password
    }

    # configure ldap attributes
    attributes = {
      :cn => vm.name,
      :objectclass => ["top", "computer"],
      :samaccountname => vm.name,
      :useraccountcontrol => '4128'
    }

    log(:info, "Calling ldap:<#{servername}> dn:<#{basedn}> attributes:<#{attributes}>")
    ldap.add(:dn => dn, :attributes => attributes)
    result = ldap.get_operation_result.code
    if result.zero?
      log(:info, "Successfully added computer:<#{vm.name}> do LDAP Server")
    else
      log(:warn, "Failed to add computer:<#{vm.name}> do LDAP Server")
    end
    return result
  end

  log(:info, "CFME Automate Method Started")

  # dump all root attributes to the log
  dump_root

  # get vm object from root
  vm = $evm.root['vm']
  raise "$evm.root['vm'] not found" if vm.nil?
  log(:info, "Found VM:<#{vm.name}>")

  result = call_ldap(vm)

  # Exit method
  log(:info, "CFME Automate Method Ended")
  exit MIQ_OK

  # Set Ruby rescue behavior
rescue => err
  log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
  exit MIQ_STOP
end