Скрипт для записи в атрибут Description объекта-компьютера в AD имени текущего «залогоненного» пользователя. Дубль два.

Сегодня опубликую скрипт на PowerShell, поэтому «буду краток» (с) ;) Ниже приведен скрипт, который выполняет те же самые действия (и даже чуть больше), что и скрипт на VBScript в предыдущем посте.

####################################################
# SetSompDesc.ps1 20090112 ShS
#
#Записываем в атрибут Description каждого объекта Computer, имя, залогоненого на нем пользователя
####################################################
cls
#Функция возращает true, если заданный хост пингуется и false  - в противном случае (спасибо Xaerg'у)
function Test-Host ($Name)
{
    $ping = new-object System.Net.NetworkInformation.Ping
    trap {Write-Verbose "Ошибка пинга"; $False; continue}
    if ($ping.send($Name).Status -eq "Success" ) { $True }
    else { $False }
}
#Filter Where-Online
#{
#    $ping = new-object System.Net.NetworkInformation.Ping
#    trap {Write-Verbose "Ошибка пинга"; Continue}
#    if ($ping.send($_).Status -eq "Success" ) { $_ }
#}
#
#Зададим корневое OU, с которого будет начат поиск компьютеров
$SearchRoot="dom.local/ORG/Workstations"
#

 $Comps = Get-QADComputer -ErrorAction SilentlyContinue -SearchRoot $SearchRoot -SizeLimit 0 #|Select-Object -property "Name","Description"
 foreach ($Comp in $Comps)
 {
  if (Test-Host $Comp.Name)
     {
    $LoggedonUserName = (gwmi Win32_ComputerSystem -ErrorAction SilentlyContinue -ComputerName $Comp.Name).UserName
    Write-Host "CompName=",$Comp.Name, "  CompDescription=", $Comp.Description, "  LoggedonUser=", $LoggedonUserName
    if (($Comp.Description -ne $LoggedonUserName) -and ($LoggedonUserName -ne $null))
        {
        Write-Host "`nОтсутствует (или устаревшее) описание компа!`nМеняем на новое...`n`n"
        Set-QADObject $Comp.DN -Description $LoggedonUserName | Out-Null
        }
     }
 }

В отличие от своего предшественника (скрипта на VBScript), этот скрипт сначала проверяет доступность компьютера при помощи ping’а и, лишь затем, опрашивает удаленный компьютер для выяснения имени «залогонненого» на нем пользователя.
Скрипт использует командлеты ActiveRoles Management Shell for Active Directory от Quest Software.

29 Comments

  1. Pingback: Поиск компьютера в AD по содержимому атрибута Description с последующей передачей в окно «Предложение удаленной помощи» имени найденного компью

  2. Pingback: Поиск компьютера в AD по содержимому атрибута Description с последующей передачей в окно «Предложение удаленной помощи» имени найденного компью

    • На вопрос “у меня что-то не рабоает. что делать?”, обычно отвечают: “надо что-то починить”.

      что конкретно “не работает”? и как не рабоатет? Сообщения об ошибке где? (не вижу)

  3. Проблема такая, пробовал Ваш скрипт на vbs и на PoSh, скрипт отрабатывает без ошибок но выдает следующее:

    CompName= XP CompDescription= LoggedonUser=

    и т.д.

    Соответственно ничего не меняет в описании, запускал из под админдомена, в чем может быть проблема?

    • >Соответственно ничего не меняет в описании, запускал из под админдомена, в чем может быть проблема?

      ЕМНИП, если LoggedonUser принимает значение пусто, то скрипт не меняет описание компьютера (что логично). Принимать же значение пусто он может, если на опрашиваемом компьютере никто не залогонен, либо произошла ошибка опроса, или, если пользователь, в контексте которого работает скрипт, не обладает правами локадмина на опрашиваемом компьютере.

      Удалите (временно) из скрипта обработчики ошибок: замените в строке

      $LoggedonUserName = (gwmi Win32_ComputerSystem -ErrorAction SilentlyContinue -ComputerName $Comp.Name).UserName

      SilentlyContinue на Stop
      Если будет возникать ошибка – запостите ее сюда.

      • Get-WmiObject : Сервер RPC недоступен. (Исключение из HRESULT: 0x800706BA)
        D:\11.ps1:31 знак:30
        + $LoggedonUserName = (gwmi <<<< Win32_ComputerSystem -ErrorAction Stop -ComputerName $Comp.Nam
        + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
        + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

        • Собственно, в сообщении об ошибке все написано: Сервер RPC недоступен
          Проверяйте, что у вас с RPC и/или WMI. У вас файервол на проблемной машине (при обращении, к которой происходит ошибка) не запущен ли?

          • Собстна поковырял еще, при отключенном файерволе работает (это гут) но нужно при включенном. Вчера поиграл с разрешениями в нем, ошибка та же RPC, сегодня пришел ничего не меняя прокатило на семерке, компы в домене xp и 7 50х50. Буду делать волшебство дальше, спасибо за помощь!!

            • Это никакое не волшебство. RPC по дефолту использует заранее не известный динамический диапазон портов для взаимодействия. Посему, чтобы пробросить RPC через Firewall надо внести изменнеия в реестр, чтобы зафиксировать этот диапазон портов, а, затем, уже можно будет его легко пробросить.

    • Замените строку
      Set-QADObject $Comp.DN -Description $LoggedonUserName | Out-Null
      на 2 строки:
      $DisplayName=Get-QADUser $LoggedonUserName|select -ExpandProperty DisplayName
      Set-QADObject $Comp.DN -Description $DisplayName| Out-Null

  4. а можно добавить в описание еще ipv4address для еще большего удовлетворения, например в скобках ?

    • Конечно можно. IP-адрес, например, можно получить следующим способом: gwmi Win32_NetworkAdapterConfiguration|?{$_.IPEnabled}|%{$_.IPAddress}

      • $IP = gwmi Win32_NetworkAdapterConfiguration -ErrorAction SilentlyContinue -ComputerName $Comp.Name |?{$_.IPEnabled}|%{$_.IPAddress}

        Write-Host “CompName=”,$Comp.Name, “CompDescription=”, $Comp.Description, “LoggedonUser=”, $LoggedonUserName, “IPv4=”, $IP
        if (($Comp.Description -ne $LoggedonUserName) -and ($LoggedonUserName -ne $null))
        {
        Write-Host “`nОтсутствует (или устаревшее) описание компа!`nМеняем на новое…`n`n”
        $DisplayName=Get-QADUser $LoggedonUserName|select -ExpandProperty DisplayName
        Set-QADObject $Comp.DN -Description “$DisplayName ($IP)” | Out-Null

        вот так сделал, спасибо за хороший скрипт

  5. CompName= xxx CompDescription= cccc LoggedonUser= yyy\i.kkk
    Get-WmiObject : Отказано в доступе. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED))
    C:\tmp\DescriptionComp.ps1:31 знак:30
    + $LoggedonUserName = (gwmi <<<< Win32_ComputerSystem -ErrorAction SilentlyContinue -ComputerName $Comp.Name).User
    Name
    + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Get-WmiObject : Отказано в доступе. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED))
    C:\tmp\DescriptionComp.ps1:33 знак:12
    + $IP = gwmi <<<< Win32_NetworkAdapterConfiguration -ErrorAction SilentlyContinue -ComputerName $Comp.Name |?{$_.I
    PEnabled}|%{$_.IPAddress}
    + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    на некоторых компах происходит такая ошибка, при которой залогиненый юзер прописывается в описание следующего компа, на котором он на самом деле не залогинен

    куда копнуть?

    • замените
      $LoggedonUserName = (gwmi Win32_ComputerSystem -ErrorAction SilentlyContinue -ComputerName $Comp.Name).UserName

      на
      $LoggedonUserName =$null
      try {
      $LoggedonUserName = (gwmi Win32_ComputerSystem -ErrorAction Stop -ComputerName $Comp.Name).UserName
      }
      catch {
      Write-Host “Ошибка при получении имени пользователя на компьютере $($Comp.Name)”
      }

      это позволит правильно обработать возникающие у вас ошибки. Что касается причины возникновения отказа в доступе, то с этим надо будет разбираться уже вам самому.

      Upd.

  6. еще есть ошибки

    Get-QADUser : Не удается проверить аргумент для параметра “Identity”. Аргумент пустой или имеет значение NULL. Укажите
    не пустой аргумент, не имеющий значение NULL, после чего повторите выполнение команды.
    C:\tmp\DescriptionComp.ps1:32 знак:26
    + $DisplayName=Get-QADUser <<<< $LoggedonUserName|select -ExpandProperty DisplayName
    + CategoryInfo : InvalidData: (:) [Get-QADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlet
    s.GetUserCmdlet

    тут даже не знаю на что думать, по отдельности все прекрасно отрабатывает

  7. в начале цикла надо бы добавить обнуление $LoggedonUserName а то при невозможности прочитать инфу с хоста в АД пишется от предыдущего

    • Да, вы правы, я упустил из виду то, что -ErrorAction SilentlyContinue, к сожалению не гарантирует корретной обработки всех ошибок, которые могут возникнуть при обращении к WMI, а это значит, что $LoggedonUserName не обнулится, в случае возникновения некоторых ошибок.
      Лучше будет вообще вынести вызов wmi внутрь блока try, например так:
      try {
      $LoggedonUserName=(gwmi Win32_ComputerSystem -ErrorAction SilentlyContinue -ComputerName $Comp.Name).UserName
      }
      catch {
      $LoggedonUserName=$null
      }

  8. Спасибо за скрипт, только почему стартует через раз? Три раза запускал копированием в ActiveRoles Management Shell for Active Directory x64, на четвертый запускается….

    • Ну, скрипт не может не стартовать, если вы его запустили на исполнение, значит он стартанул. Попробуйте запустить его под отладчиком и посмотреть, где у вас возникает проблема.

  9. При выполнении выдает ошибку:
    Имя “Get-QADComputer” не распознано как имя командлета, функции, файла скрипта или выполняемой программы. Проверьте пра вильность написания имени, а также наличие и правильность пути, после чего повторите попытку.
    строка:1 знак:26
    + $Comps = Get-QADComputer <<<< -ErrorAction SilentlyContinue -SearchRoot $SearchRoot -SizeLimit 0 #|Select-Object -p
    roperty "Name","Description"
    + CategoryInfo : ObjectNotFound: (Get-QADComputer:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    и еще вопрос как указать для сканирования контейнер в домене?

    • Это потому, что вы не установили ActiveRoles Management Shell for Active Directory от Quest software, которые, видимо, были куплены Dell’ом и теперь доступны по следующему URL https://support.software.dell.com/download-install-detail/5024645

      Про контейнер см скрипт:
      #Зададим корневое OU, с которого будет начат поиск компьютеров
      $SearchRoot=”dom.local/ORG/Workstations”

  10. Скрипт для записи в атрибут Description объекта-компьютера в AD имени текущего «залогоненного» пользователя + ip (ps3-4)

    Import-Module ActiveDirectory
    #$erroractionpreference = «SilentlyContinue» # Раскоментить если хотите пропускать ошибки
    foreach ($comp in (Get-ADComputer -filter * -SearchBase «OU=Отдел,DC=company,DC=local» | select -expand name)) #foreach {$_.name} ))
    { $ping = new-object System.Net.NetworkInformation.Ping
    trap {Write-Verbose $false; » $comp — Ошибка пинга»; continue}
    if ($ping.send($comp).Status -eq «Success»)
    {
    $useroncomp = (Get-WmiObject -Class Win32_ComputerSystem -ComputerName $comp).username
    $IP = [System.Net.Dns]::GetHostAddresses(«$comp»)
    $lastuser = Get-ADUser ($useroncomp.split(«\»)[1]) -properties displayname
    Set-ADComputer $comp -Description (($lastuser.DisplayName) + » (» + $IP + «)»)
    }
    else {Write-Host $comp.name «$comp — недоступен»}
    }

  11. У меня след ошибка
    est-Host : The term ‘Test-Host’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
    included, verify that the path is correct and try again.
    At line:5 char:7
    + if (Test-Host $Comp.Name)
    + ~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Test-Host:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.