Usuário com melhor resposta
Script por grupo do AD - Adicionar possibilidade de usar um grupo dentro de outro.

Pergunta
-
Galera, achei o script abaixo e ele atende 99% do que preciso, porém, ele não verifica os membros dentro de um grupo adicionado a outro grupo. Por exemplo: Tenho os membros do GrupoA, o script funciona, porém se eu adicionar o GrupoB dentro do grupoA o script não funciona para os membros do GrupoB, funciona somente para os membros do GrupoA. Esse comportamento me obriga a adicionar usuário por usuário, que seria muito trabalhoso já que tenho grupos pré-definidos.
Alguém pode dar uma ajuda com o Script abaixo?
On Error Resume Next set wshshell = wscript.createobject("wscript.shell") set objNetwork= CreateObject("WScript.Network") strDom = objNetwork.UserDomain strUser = objNetwork.UserName Set objUser = GetObject("WinNT://" & strDom & "/" & strUser & ",user") For Each objGroup In objUser.Groups Select Case objGroup.Name Case "GrupoA" wshshell.run ("Arquivo1.bat" ), 0, true Case "GrupoX" wshshell.run ("Arquivo2.bat"), 0, true End Select Next
- Editado Fábio JrModerator terça-feira, 11 de fevereiro de 2014 16:35 Formatacao código
Respostas
-
Este erro acontece porque está tentando adicionar ao dicionário um grupo que ele já possui. O objeto dicionário não permite chaves repetidas, então tem duas opções.
1) Testar se a chave existe (estou usando o nome do grupo como chave) e se não existir então adiciona mais uma chave
2) Usar o ON ERROR RESUME NEXT para desconsiderar os erros.
Eu usei a segunda opção, além dos wscript.echo você deve ter retirado essa linha também.
Alterei agora para a primeira opção
'On Error Resume Next 'Cria Dicionário Set dGrupos = CreateObject("Scripting.Dictionary") 'Le os grupos guardando os dados no dicionario Set objSysInfo = CreateObject("ADSystemInfo") strCN = objSysInfo.UserName wscript.echo strCN Set objUser=GetObject("LDAP://" & strCN) Set colGroups = objUser.Groups For Each objGroup in colGroups Wscript.Echo objGroup.CN if not dGrupos.Exists(objGroup.CN) then dGrupos.Add objGroup.CN, objGroup.CN GetNested(objGroup) Next 'fim do carregamento do dicionario 'Ler dicionario wscript.echo "Lendo dicionarios __________=================" colKeys = dGrupos.Keys For Each strKey in colKeys Select Case dGrupos.Item(strKey) Case "GrupoA" wshshell.run ("Arquivo1.bat" ), 0, true Case "GrupoX" wshshell.run ("Arquivo2.bat"), 0, true end select Next 'Fim do script 'Subs e Functions Sub GetNested(objGroup) On Error Resume Next colMembers = objGroup.GetEx("memberOf") For Each strMember in colMembers strPath = "LDAP://" & strMember Set objNestedGroup = _ GetObject(strPath) WScript.Echo objNestedGroup.CN if not dGrupos.Exists(objNestedGroup.CN) then dGrupos.Add objNestedGroup.CN, objNestedGroup.CN GetNested(objNestedGroup) Next End Sub
Ref.: Exists Method (Script Runtime)
http://msdn.microsoft.com/en-us/library/57hdf10z(v=vs.84).aspx
Fábio de Paula Junior
- Editado Fábio JrModerator segunda-feira, 17 de fevereiro de 2014 14:12
- Sugerido como Resposta Fábio JrModerator segunda-feira, 17 de fevereiro de 2014 16:57
- Marcado como Resposta K.ryn terça-feira, 18 de fevereiro de 2014 17:50
Todas as Respostas
-
K.ryn,
Se não me engano este artigo trata deste caso
Hey, Scripting Guy!Determining a User’s Group Memberships
http://technet.microsoft.com/pt-br/magazine/2006.03.scriptingguy(en-us).aspx
On Error Resume Next SetobjUser=GetObject("LDAP://CN=Ken Myer," & _ "OU=Finance,DC=fabrikam,DC=com") Set colGroups = objUser.Groups For Each objGroup in colGroups Wscript.Echo objGroup.CN GetNested(objGroup) Next Function GetNested(objGroup) On Error Resume Next colMembers = objGroup.GetEx("memberOf") For Each strMember in colMembers strPath = "LDAP://" & strMember Set objNestedGroup = _ GetObject(strPath) WScript.Echo objNestedGroup.CN GetNested(objNestedGroup) Next End Function
Fábio de Paula Junior
-
-
K.ryn,
Exatamente, tem que informar o CN.
Veja esta modificação, vc quer o usuário corrente certo?
On Error Resume Next Set objSysInfo = CreateObject("ADSystemInfo") strCN = objSysInfo.UserName wscript.echo strCN Set objUser=GetObject("LDAP://" & strCN) Set colGroups = objUser.Groups For Each objGroup in colGroups Wscript.Echo objGroup.CN GetNested(objGroup) Next Function GetNested(objGroup) On Error Resume Next colMembers = objGroup.GetEx("memberOf") For Each strMember in colMembers strPath = "LDAP://" & strMember Set objNestedGroup = _ GetObject(strPath) WScript.Echo objNestedGroup.CN GetNested(objNestedGroup) Next End Function
Fábio de Paula Junior
-
K.ryn,
Este aqui está pronto
On Error Resume Next 'Cria Dicionário Set dGrupos = CreateObject("Scripting.Dictionary") 'Le os grupos guardando os dados no dicionario Set objSysInfo = CreateObject("ADSystemInfo") strCN = objSysInfo.UserName wscript.echo strCN Set objUser=GetObject("LDAP://" & strCN) Set colGroups = objUser.Groups For Each objGroup in colGroups Wscript.Echo objGroup.CN dGrupos.Add objGroup.CN, objGroup.CN GetNested(objGroup) Next 'fim do carregamento do dicionario 'Ler dicionario wscript.echo "Lendo dicionarios __________=================" colKeys = dGrupos.Keys For Each strKey in colKeys Select Case dGrupos.Item(strKey) Case "GrupoA" wshshell.run ("Arquivo1.bat" ), 0, true Case "GrupoX" wshshell.run ("Arquivo2.bat"), 0, true end select Next 'Fim do script 'Subs e Functions Sub GetNested(objGroup) On Error Resume Next colMembers = objGroup.GetEx("memberOf") For Each strMember in colMembers strPath = "LDAP://" & strMember Set objNestedGroup = _ GetObject(strPath) WScript.Echo objNestedGroup.CN dGrupos.Add objNestedGroup.CN, objNestedGroup.CN GetNested(objNestedGroup) Next End Sub
Vc só precisa tirar os Wscript.echo, deixei aí caso você queira testá-lo antes a partir do prompt de comando.
A vantagem de usar o dicionário é que você não corre o risco de executar um procedimento mais de uma vez.
Ref.:
The Dictionary Object
http://technet.microsoft.com/en-us/library/ee176993.aspx
Fábio de Paula Junior
- Editado Fábio JrModerator sexta-feira, 14 de fevereiro de 2014 18:18
-
Fábio, agradeço novamente a ajuda.
Executei o script e esta ocorrendo erro na linha 15, caracter 2. A mensagem é "Esta tecla já está associada com um elemento desta coleção". A linha 15 contém o seguinte conteúdo: dGrupos.Add objGroup.CN, objGroup.CN
Eu executei o script exatamente do modo que esta, apenas comentei as linhas do wscript.excho
Tem alguma sugestão?
-
Este erro acontece porque está tentando adicionar ao dicionário um grupo que ele já possui. O objeto dicionário não permite chaves repetidas, então tem duas opções.
1) Testar se a chave existe (estou usando o nome do grupo como chave) e se não existir então adiciona mais uma chave
2) Usar o ON ERROR RESUME NEXT para desconsiderar os erros.
Eu usei a segunda opção, além dos wscript.echo você deve ter retirado essa linha também.
Alterei agora para a primeira opção
'On Error Resume Next 'Cria Dicionário Set dGrupos = CreateObject("Scripting.Dictionary") 'Le os grupos guardando os dados no dicionario Set objSysInfo = CreateObject("ADSystemInfo") strCN = objSysInfo.UserName wscript.echo strCN Set objUser=GetObject("LDAP://" & strCN) Set colGroups = objUser.Groups For Each objGroup in colGroups Wscript.Echo objGroup.CN if not dGrupos.Exists(objGroup.CN) then dGrupos.Add objGroup.CN, objGroup.CN GetNested(objGroup) Next 'fim do carregamento do dicionario 'Ler dicionario wscript.echo "Lendo dicionarios __________=================" colKeys = dGrupos.Keys For Each strKey in colKeys Select Case dGrupos.Item(strKey) Case "GrupoA" wshshell.run ("Arquivo1.bat" ), 0, true Case "GrupoX" wshshell.run ("Arquivo2.bat"), 0, true end select Next 'Fim do script 'Subs e Functions Sub GetNested(objGroup) On Error Resume Next colMembers = objGroup.GetEx("memberOf") For Each strMember in colMembers strPath = "LDAP://" & strMember Set objNestedGroup = _ GetObject(strPath) WScript.Echo objNestedGroup.CN if not dGrupos.Exists(objNestedGroup.CN) then dGrupos.Add objNestedGroup.CN, objNestedGroup.CN GetNested(objNestedGroup) Next End Sub
Ref.: Exists Method (Script Runtime)
http://msdn.microsoft.com/en-us/library/57hdf10z(v=vs.84).aspx
Fábio de Paula Junior
- Editado Fábio JrModerator segunda-feira, 17 de fevereiro de 2014 14:12
- Sugerido como Resposta Fábio JrModerator segunda-feira, 17 de fevereiro de 2014 16:57
- Marcado como Resposta K.ryn terça-feira, 18 de fevereiro de 2014 17:50
-
O On Error Resume Next eu comentei para tentar entender o motivo de não ter funcionado.
Percebi que o script entra em loop por que eu tenho o grupoB dentro do grupoA, e o grupoA dentro do grupoB Esse comportamento ficou evidente quando removi o comentário das linhas do wscript.echo. Sei que esta errado (no AD) mas não posso alterar agora. Existe um meio de lidar com esse comportamento?
-
Pensei em uma abordagem diferente, mediante o loop e a quantidade de grupos.
A condição Case suporta outros grupos na mesma linha? Por exemplo:
Case "GrupoA" or "GrupoC" or "GrupoD"
wshshell.run ("Arquivo1.bat" ), 0, true
Obrigado,
- Editado K.ryn segunda-feira, 17 de fevereiro de 2014 15:16
-