none
Script procura users desabilitados e move para outra OU RRS feed

  • Pergunta

  • Olá, boa tarde!

    Estive pesquisando um script em VB que faça uma consulta no AD e ao encontrar usuários desabilitados, mova-os para uma OU específica. Encontrei alguns e testei-os, porém está ocorrendo um erro que não estou conseguindo solucionar. Poderiam me auxiliar neste que segue abaixo?

    Option Explicit
    
    Dim strTargetOU, objTargetOU, adoConnection, adoCommand, strBase
    Dim strFilter, strAttributes, strQuery, adoRecordset
    Dim strUserDN
    
    ' Specify the Distinguished Name of the Organizational Unit into
    ' which disabled user objects will be moved.
    strTargetOU = "OU=teste,DC=teste,DC=com,DC=br"
    
    ' Bind to target OU.
    Set objTargetOU = GetObject("LDAP://" & strTargetOU)
    
    ' Use ADO to search the domain.
    Set adoConnection = CreateObject("ADODB.Connection")
    Set adoCommand = CreateObject("ADODB.Command")
    adoConnection.Provider = "ADsDSOOBject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Specify the base of the search.
    strBase = "OU=Desativados,DC=teste,DC=com,DC=br"
    
    ' Filter to retrieve all disabled user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
        & "(userAccountControl:1.2.840.113556.1.4.803:=2))"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"
    
    ' Construct the LDAP syntax query.
    strQuery = "<LDAP://" & strBase & ">;" & strFilter _
        & ";" & strAttributes & ";oneLevel"
    
    ' Run the query.
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False
    
    Set adoRecordset = adoCommand.Execute
    
    ' Enumerate the recordset.
    Do Until adoRecordset.EOF
        strUserDN = adoRecordset.Fields("distinguishdName").Value
        ' Move the user.
        objTargetOU.MoveHere "LDAP://" & strUserDN, vbNullString
        adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    Erro:

    script: C:\moveDisables.vbs
    line: 45
    Char: 5
    Error: Item Cannot be found in the collection corresponding to the requested name or ordinal.
    Code: 800A0CC1
    Source: ADODB.Recordset

    segunda-feira, 14 de dezembro de 2015 15:54

Respostas

  • Olá Fabio,

    Esse último erro indica que o computador onde você rodou o script não possui os objetos do Active Directory, você precisa rodar esse script em um servidor que possua as ferramentas do Active Directory instalado. Eu acabei testando o script aqui no meu ambiente e tinha mais alguns itens que precisavam de ajustes. Agora testei e funcionou. Dá uma olhada abaixo. Qualquer coisa, avise.

    Abraço,
    Gustavo

    Option Explicit
    
    Dim strTargetOU, objTargetOU, adoConnection, adoCommand, strBase
    Dim strFilter, strAttributes, strQuery, adoRecordset
    Dim strUserDN
    
    ' Specify the Distinguished Name of the Organizational Unit into
    ' which disabled user objects will be moved.
    strTargetOU = "OU=teste,DC=gm9,DC=com"
    
    ' Specify the base of the search.
    strBase = "OU=Desativados,DC=gm9,DC=com"
    
    ' Bind to target OU.
    Set objTargetOU = GetObject("LDAP://" & strBase)
    
    ' Use ADO to search the domain.
    Set adoConnection = CreateObject("ADODB.Connection")
    Set adoCommand = CreateObject("ADODB.Command")
    adoConnection.Provider = "ADsDSOOBject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Filter to retrieve all disabled user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
        & "(userAccountControl:1.2.840.113556.1.4.803:=2))"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"
    
    ' Construct the LDAP syntax query.
    strQuery = "<LDAP://" & strTargetOU & ">;" & strFilter _
        & ";" & strAttributes & ";oneLevel"
    
    ' Run the query.
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False
    
    Set adoRecordset = adoCommand.Execute
    
    ' Enumerate the recordset.
    Do Until adoRecordset.EOF
        strUserDN = adoRecordset.Fields("distinguishedName").Value
        ' Move the user.
    	wscript.echo "Moving user: " & strUserDN
        objTargetOU.MoveHere "LDAP://" & strUserDN, vbNullString
        adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    • Marcado como Resposta Fábio B Z segunda-feira, 14 de dezembro de 2015 18:06
    segunda-feira, 14 de dezembro de 2015 17:14
  • Simples!

    c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -File C:\scripts\MyPoShScript.ps1 -ExecutionPolicy RemoteSigned -WindowStyle Hidden

    • Marcado como Resposta Fábio B Z quarta-feira, 16 de dezembro de 2015 10:36
    terça-feira, 15 de dezembro de 2015 12:05

Todas as Respostas

  • Ola Fábio,

    Tem um erro na sintaxe da linha 45, ao invés de distinguishedName, está distinguishdName (falta um 'e'). Teste esse script abaixo. Qualquer dúvida, avise.

    Se a resposta fornecida nessa thread ajudou na sua solução, não esqueça de marcar como resposta!

    Abraço,
    Gustavo Zimmermann Montesdioca - MTAC, MCT
    Blog: www.gm9.com.br

    Option Explicit
    
    Dim strTargetOU, objTargetOU, adoConnection, adoCommand, strBase
    Dim strFilter, strAttributes, strQuery, adoRecordset
    Dim strUserDN
    
    ' Specify the Distinguished Name of the Organizational Unit into
    ' which disabled user objects will be moved.
    strTargetOU = "OU=teste,DC=teste,DC=com,DC=br"
    
    ' Bind to target OU.
    Set objTargetOU = GetObject("LDAP://" & strTargetOU)
    
    ' Use ADO to search the domain.
    Set adoConnection = CreateObject("ADODB.Connection")
    Set adoCommand = CreateObject("ADODB.Command")
    adoConnection.Provider = "ADsDSOOBject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Specify the base of the search.
    strBase = "OU=Desativados,DC=teste,DC=com,DC=br"
    
    ' Filter to retrieve all disabled user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
        & "(userAccountControl:1.2.840.113556.1.4.803:=2))"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"
    
    ' Construct the LDAP syntax query.
    strQuery = "<LDAP://" & strBase & ">;" & strFilter _
        & ";" & strAttributes & ";oneLevel"
    
    ' Run the query.
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False
    
    Set adoRecordset = adoCommand.Execute
    
    ' Enumerate the recordset.
    Do Until adoRecordset.EOF
        strUserDN = adoRecordset.Fields("distinguishedName").Value
        ' Move the user.
        objTargetOU.MoveHere "LDAP://" & strUserDN, vbNullString
        adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close


    segunda-feira, 14 de dezembro de 2015 16:00
  • Olá Gustavo,

    obrigado por responder, desculpe não observar esse detalhe :(

    Bem, testando seu script o erro foi:

    Linha 41
    Caract.: 1
    Erro: Não há tal objeto no servidor.
    Código 80040E37

    segunda-feira, 14 de dezembro de 2015 16:12
  • Olá Fabio,

    Esse último erro indica que o computador onde você rodou o script não possui os objetos do Active Directory, você precisa rodar esse script em um servidor que possua as ferramentas do Active Directory instalado. Eu acabei testando o script aqui no meu ambiente e tinha mais alguns itens que precisavam de ajustes. Agora testei e funcionou. Dá uma olhada abaixo. Qualquer coisa, avise.

    Abraço,
    Gustavo

    Option Explicit
    
    Dim strTargetOU, objTargetOU, adoConnection, adoCommand, strBase
    Dim strFilter, strAttributes, strQuery, adoRecordset
    Dim strUserDN
    
    ' Specify the Distinguished Name of the Organizational Unit into
    ' which disabled user objects will be moved.
    strTargetOU = "OU=teste,DC=gm9,DC=com"
    
    ' Specify the base of the search.
    strBase = "OU=Desativados,DC=gm9,DC=com"
    
    ' Bind to target OU.
    Set objTargetOU = GetObject("LDAP://" & strBase)
    
    ' Use ADO to search the domain.
    Set adoConnection = CreateObject("ADODB.Connection")
    Set adoCommand = CreateObject("ADODB.Command")
    adoConnection.Provider = "ADsDSOOBject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Filter to retrieve all disabled user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
        & "(userAccountControl:1.2.840.113556.1.4.803:=2))"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"
    
    ' Construct the LDAP syntax query.
    strQuery = "<LDAP://" & strTargetOU & ">;" & strFilter _
        & ";" & strAttributes & ";oneLevel"
    
    ' Run the query.
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False
    
    Set adoRecordset = adoCommand.Execute
    
    ' Enumerate the recordset.
    Do Until adoRecordset.EOF
        strUserDN = adoRecordset.Fields("distinguishedName").Value
        ' Move the user.
    	wscript.echo "Moving user: " & strUserDN
        objTargetOU.MoveHere "LDAP://" & strUserDN, vbNullString
        adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    • Marcado como Resposta Fábio B Z segunda-feira, 14 de dezembro de 2015 18:06
    segunda-feira, 14 de dezembro de 2015 17:14
  • Funcionou perfeitamente Gustavo, obrigado.

    segunda-feira, 14 de dezembro de 2015 18:06
  • Gustavo, fiz o teste especificando uma raiz de "N" OUs, pois a minha ideia seria que o script varresse o AD procurando os usuários desabilitados, porém, ao contrario do que eu imaginava, o script apenas varre a OU específica e não entra nas OUs de dentro dessa. Alguma ideia de como resolver esse problema?
    segunda-feira, 14 de dezembro de 2015 22:51
  • Com o script abaixo, em PS, consigo fazer o que pretendo, porém estou com dificuldades de criar um .bat chamando esse comando.

    import-module activedirectory
    
    Import-Module ServerManager
    
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase “OU=consulta,DC=teste,DC=com,DC=br” 
    |Move-ADObject –TargetPath “OU=Bloqueios,DC=teste,DC=com,DC=br”
    Criei um .ps1 e tento fazer a chamada dele com: powershell -command "& 'c:\moveUsersDesabilitados.ps1' "

    E obtenho o erro:

    Move-ADObject : Acesso negado
    Em C:\moveUsersDesabilitados.ps1:10 caractere:14
    + Move-ADObject <<<<  -TargetPath "OU=Bloqueios,DC=teste,DC=com,DC=br"
        + CategoryInfo          : PermissionDenied: (CN=teste,OU=Blo...le,DC=com,DC=br:ADAccount) [Move-ADObject], UnauthorizedAccessException
        + FullyQualifiedErrorId : Acesso negado,Microsoft.ActiveDirectory.Management.Commands.MoveADObject



    • Editado Fábio B Z segunda-feira, 14 de dezembro de 2015 23:28
    segunda-feira, 14 de dezembro de 2015 23:06
  • Você não precisa criar um .bat e chama-lo a partir do Command Prompt. Salve o script como .ps1 e chame o mesmo diretamente a partir de uma janela do PowerShell elevada como administrator.

    Outro detalhe: remova o parâmetro -SearchBase, pois ele irá indicar ao command let que a pesquisa deve ser feita em uma OU específica. Retirando-o a pesquisa será feita em todo o domínio.

    terça-feira, 15 de dezembro de 2015 11:14
  • Olá Anderson,

    sem o .bat como posso fazer para agendar no agendador de tarefas e executá-lo como admin?

    Algo assim: powershell -file "& 'script.ps1' "? 


    terça-feira, 15 de dezembro de 2015 11:37
  • Simples!

    c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -File C:\scripts\MyPoShScript.ps1 -ExecutionPolicy RemoteSigned -WindowStyle Hidden

    • Marcado como Resposta Fábio B Z quarta-feira, 16 de dezembro de 2015 10:36
    terça-feira, 15 de dezembro de 2015 12:05