Назад | Перейти на главную страницу

Компьютерные метрики AD

Я пытаюсь найти правильный код для сценария Powershell. Я хочу, чтобы он посмотрел на все наши контроллеры домена и использовал самый последний файл lastlongondate. После того, как у него есть данные, я хочу, чтобы он классифицировал их через ОС, чтобы он сказал Windows 10 - 100 Server 2008 - 10 ex .... Кажется, я не могу понять, как заставить его проверять все контроллеры на наличие соответствующих данных. Это то, что у меня есть. Кто-нибудь видит, что я делаю не так?

#Functions
function ImportADModule
{
  Import-Module ActiveDirectory
  if (!($?))
  { 
    Add-WindowsFeature RSAT-AD-PowerShell
    Import-Module ActiveDirectory
  }
}

function GetDN
{
  param($domain)
  $names = $domain.Split(".")
  $bFirst = $true
  foreach ($name in $names)
  {
    if ($bFirst)
    {
      $dn += "DC=" + $name
      $bFirst = $false
    }
    else { $dn += ",DC=" + $name }
  }
  return $dn
}

function GetDNs
{
  param($domains)
  $dns = @{}
  foreach ($domain in $domains)
  {
    $dns.Add($domain, (GetDN -domain $domain))
  }
  return $dns
}

function GetOSCountsPerDomain
{
  param($dns, $enabled, $daysOld)
  $osCounts = @{}
  $cutOffDate = ((Get-Date).Adddays(-($daysOld))).ToFileTime()
  Write-Host "Getting Data" -NoNewline -ForegroundColor Yellow

  $filter = "(PwdLastSet -gt {0}) -and (Enabled -eq '{1}')" -f $cutOffDate, $enabled
  foreach ($domain in $dns.GetEnumerator())
  {
    $i = 0
    $domains = @{}
    Write-Host "." -NoNewline -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter $filter -SearchBase $domain.Value -Server $domain.Key -Properties OperatingSystem
    foreach ($computer in $computers)
    {
      if ($computer.OperatingSystem -eq $null) { $os = 'NULL'}
      else { $os = $computer.OperatingSystem }
      try { $domains.Add(($os + " - " + $osver), 1) }
      catch { $domains.Set_Item(($os + " - " + $osver), ($domains.Get_Item($os + " - " + $osver))+1) }
    }
    $osCounts.Add($domain.Key, $domains)
  }
  Write-Host
  return $osCounts
}

function DisplayOutput
{
  param($osCounts)
  Write-Host
  foreach ($osCount in $osCounts.GetEnumerator())
  {
    Write-Host $OSCount.Key -ForegroundColor Green
    $osCount.Value.GetEnumerator() | Sort-Object Value -Descending | Format-Table -AutoSize
  }
}

#Main

#Import AD Module for PowerShell
ImportADModule

#Get list of domains from current forest
$Domains = (Get-ADForest).domains

#Get hash table of domains and distinguished names from current forest
$DNs = GetDNs -domains $Domains

#Get OS counts per domain (specify age here)
$OSCounts = GetOSCountsPerDomain -dns $DNs -enabled $true -daysOld 7

#Display Results
$Body = DisplayOutput -osCounts $OSCounts 

#Send email settings
$email = @{
From = "email"
To = "email"
Subject = "Operating System Counts"
SMTPServer = "mail.mail.org"
Body = $body| Out-String
}

send-mailmessage @email

Приведенное ниже должно делать то, что вы ищете. Я не добавил часть «отправить письмо». Просто ответил на ваш конкретный вопрос о контроллерах домена и их количестве.

$domaincontrollers = Get-ADDomainController

$dcinfo = foreach($computer in $domaincontrollers)
          {
              Get-Adcomputer -Identity $computer.Name -Properties LastLogonDate,OperatingSystem
          }

$dcinfo | Group-Object OperatingSystem

ОБНОВЛЕНИЕ - перечитывая ваш вопрос, я не уверен, хотите ли вы, чтобы все компьютеры из контроллера домена имели самую последнюю дату последнего входа в систему. В этом случае, чтобы получить Контроллер домена с самой последней датой входа в систему, а затем все компьютеры с этого сервера, вы должны использовать следующее. Благодаря этому ссылка на сайт.

$domaincontrollers = Get-ADDomainController
$lastlogondomaincontroller = $domaincontrollers | Foreach-Object {$_.LastLogonDate = $_.LastLogonDate; $_} | `
                             Group-Object Name | `
                             Foreach-Object {$_.Name | Sort-Object LastLogonDate | Select-Object -Last 1}

Get-Adcomputer -Filter * -Server $lastlogondomaincontroller -Properties LastLogonDate,OperatingSystem | Group-Object OperatingSystem   

ОБНОВЛЕНИЕ 2 - После комментариев.

$domaincontrollers = (Get-ADForest).Domains | ForEach-Object { Get- ADDomainController -Filter * -Server $_ }

$allcomputersfromalldcs = foreach($computer in $domaincontrollers)
                          {
                              Get-Adcomputer -filter * -server $computer.Name -Properties LastLogonDate,OperatingSystem
                          }

$uniquecomputers = $allcomputersfromalldcs | Select-Object Name,OperatingSystem,LastLogonDate | Sort-Object Name,LastLogonDate | Select-Object Name,OperatingSystem,LastLogonDate -Unique

$uniquecomputers | Group-Object OperatingSystem

Ответ Обновление 2 получает все ваши контроллеры домена, а затем проверяет наличие всех компьютеров на каждом из ваших контроллеров домена. Поскольку будут дублирующиеся машины, $ uniquecomputers берет все компьютеры, сортирует их по имени и дате последней регистрации. Затем я использую -Unique, чтобы получить только одно имя машины.

Затем вы можете использовать Group-Object для получения значений. Если вам нужны фактические номера электронной почты, вы можете использовать

$uniquecomputers | Group-Object OperatingSystem | Select-Object Count,OperatingSystem

Я также сохранил вещи в переменных, чтобы вы могли использовать их для своей электронной почты, если это необходимо.

Надеюсь, это то, что вы искали.

Спасибо, Тим.