Как бесплатно создать отчет по инвентаризации Windows Server с помощью PowerShell — CloudSavvy IT

2 min


Логотип Powershell

PowerShell используется многими администраторами серверов. Естественно, одна из наиболее часто используемых задач — это возможность создавать сценарии и функции для инвентаризации ваших серверов и понимания того, что имеется в вашей среде.

Хотя есть много способов сделать это, с различными уровнями сложности, мы собираемся создать довольно простой, но эффектный отчет по инвентаризации Windows Server в этой статье.

Предпосылки

Эта статья будет практической. Если вы намереваетесь следовать, сначала убедитесь, что у вас есть следующие предварительные условия:

  • Работа на присоединенном к домену Active Directory (AD) Windows 10 ПК
  • Установите модуль ActiveDirectory PowerShell из Инструментарий RSAT,
  • Иметь разрешение запрашивать учетные записи компьютеров AD
  • Может выполнять удаленные запросы WMI / CIM на удаленных компьютерах
  • Есть PowerShell Remoting доступно на удаленных компьютерах

Получение серверов

Основой сценария, который мы создаем, являются сами серверы. Вы можете записать их по отдельности в текстовом файле, который читается, или в массиве внутри самого скрипта, но используя PowerShell, мы можем сделать это лучше. Чтобы сделать сценарий более динамичным и не требовать от нас его изменения при каждом добавлении нового сервера, мы можем использовать Active Directory (AD), чтобы получить список объектов компьютера в данной организационной единице (OU).

Ниже мы используем ActiveDirectory модуль, доступный в Инструментарий RSAT, чтобы запросить Servers OU и получить все объекты компьютера через Get-ADComputer,

Import-Module ActiveDirectory

$OU = 'OU=Servers,DC=domain,DC=local'

$Params = @{
    "SearchBase" = $OU
    "Filter"     = '*'
}

$Servers = Get-ADComputer @Params

На этом этапе мы могли бы отфильтровать только свойство name, чтобы заполнить $servers переменная, но часто очень полезно иметь весь возвращаемый объект для последующего использования.

Определение данных для сбора

Теперь, когда у нас есть наши серверы, нам нужно выяснить, что именно мы должны собирать с каждого сервера. Одна из причин, по которой важно сохранить полный объект AD, — это объединение этих данных с данными непосредственно с самого сервера, чтобы получить более полное представление о вашей среде.

На практике как выглядит нечто подобное? Давайте перечислим некоторые свойства, которые было бы очень полезно знать.

Значения сервера

  • Имя хоста сервера
  • Свободное место на диске
  • Память
  • Сетевые соединения

AD Значения

  • Последний пароль
  • Последний вход
  • DNS-имя хоста

Получение информации о сервере

Как мы собираем эту информацию в нашем списке возвращенных серверов? Поскольку у нас есть список серверов, нам придется перебирать $Servers объект и запрос. Начиная с простого Foreach-Object Цикл ниже, мы можем создать пользовательский объект для хранения наших значений.

$Servers | Foreach-Object {
    [PSCustomObject]@{
        "ServerHostName"     = $_.Name
        "Description"        = $_.Description
        "FreeDiskSpace"      = $Null
        "TotalMemory"        = $Null
        "NetworkConnections" = $Null
        "PasswordLastSet"    = $_.pwdLastSet
        "LastLogon"          = $_.lastLogon
        "DNSHostName"        = $_.DNSHostName
        "CreationDate"       = $_.WhenCreated
    }
}

Как вы можете сказать, сохраняя полный объект из Active Directory при первом получении компьютеров, мы можем заполнять широкий спектр информации. К сожалению, это не вся информация, которая нам нужна.

Чтобы получать информацию с каждого сервера, мы будем использовать знакомый интерфейс для многих администраторов серверов, а именно интерфейс инструментария управления Windows (WMI). Вы можете заметить, что используемые ниже командлеты взяты из интерфейса общей информационной модели (CIM), для которого WMI является реализацией этого стандарта Microsoft.

Получите свободное место на диске

Используя доступный класс WMI Win32_LogicalDiskмы можем получить все доступные диски и их свободное место. Когда мы впервые запускаем команду, Get-CimInstance -ClassName Win32_LogicalDiskвы можете заметить, что он не совсем читается в выводе по умолчанию.

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

$Disks = Get-CimInstance -ClassName Win32_LogicalDisk

$DisksResult = $Disks | Foreach-Object {
    [PSCustomObject]@{
        "Drive"     = $_.DeviceID
        "FreeSpace" = [Math]::Round(($_.FreeSpace / 1GB),2)
    }
}

$DisksResult

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

Но что, если мы хотим предупредить о нехватке места на диске? Было бы неплохо немного расширить это, чтобы установить флаг на каждом диске, который соответствует этому условию. Сравнивая свободное пространство с общим доступным пространством, мы видим, что оно меньше 10% или 10 ГБ. Причина для -or Условием является то, что на очень больших дисках 10% могут быть очень щедрыми, поэтому установка абсолютного лимита помогает.

$Disks = Get-CimInstance -ClassName Win32_LogicalDisk

$DisksResult = $Disks | Foreach-Object {
  $FreeSpace  = [Math]::Round(($_.FreeSpace / 1GB),2)
  $TotalSpace = [Math]::Round(($_.Size / 1GB),2)

  If ( ($FreeSpace / $TotalSpace -LT 0.10) -Or $FreeSpace -LT 10 ) {
    $LowDiskSpace = $True
  } Else {
    $LowDiskSpace = $False
  }

    [PSCustomObject]@{
        "Drive"        = $_.DeviceID
    "FreeSpace"    = $FreeSpace
    "LowDiskSpace" = $LowDiskSpace
    }
}

$DisksResult

Как вы можете сказать сейчас, у нас есть большой набор информации, которую нужно сохранить на наших серверах.

Как% 20to% 20Build% 20a% 20Windows% 20Server% 20Inventory% 20Report% 20for / Untitled% 202.png

Получите доступную память

Полезно знать, сколько ОЗУ выделено для каждого сервера, особенно в среде виртуальных машин. Если вы обнаружите, что некоторые из них переполнены, вы можете сэкономить ценные ресурсы, правильно выбрав серверы. К счастью, это гораздо проще получить.

Используя Win32_PhysicalMemory WMI класс, мы можем суммировать все возвращенные Capacity свойства, чтобы получить общую память.

(Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB

Получить все сетевые подключения

Наконец, мы хотим получить все сетевые соединения вместе. Это полезно знать, если определенный сервер имеет несколько интерфейсов, о которых нужно беспокоиться. Используя на этот раз немного другой механизм, мы используем Get-NetAdapter Командлет, но так как этот не имеет ComputerName Параметр, мы будем использовать PS Remoting, чтобы вызвать его локально на целевом сервере и вернуть результаты в наш скрипт.

$NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock {
    Get-NetAdapter -Physical | Select-Object Name, Status, LinkSpeed
}

Наш вывод будет выглядеть примерно так, как показано ниже, и мы можем сохранить его в нашем скрипте.

Имейте в виду, что для Invoke-Command для работы PS Remoting необходимо будет настроить на целевых серверах.

Собираем все вместе

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

Import-Module ActiveDirectory

$OU = 'OU=Servers,DC=domain,DC=local'

$Params = @{
    "SearchBase" = $OU
    "Filter"     = '*'
}

$Servers = Get-ADComputer @Params

$Servers | Foreach-Object {
  $Disks = Get-CimInstance -ComputerName $_.DnsHostName -ClassName Win32_LogicalDisk

  $DisksResult = $Disks | Foreach-Object {
    [PSCustomObject]@{
      "Drive"     = $_.DeviceID
      "FreeSpace" = [Math]::Round(($_.FreeSpace / 1GB),2)
    }
  }
  
  $NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock {
    Get-NetAdapter -Physical | Select-Object Name, Status, LinkSpeed
  }

    [PSCustomObject]@{
        "ServerHostName"     = $_.Name
        "Description"        = $_.Description
        "FreeDiskSpace"      = $DisksResult
        "TotalMemory"        = ((Get-CimInstance -ComputerName $_.DnsHostName -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB)
        "NetworkConnections" = $NetworkConnections
        "PasswordLastSet"    = $_.pwdLastSet
        "LastLogon"          = $_.lastLogon
        "DNSHostName"        = $_.DNSHostName
        "CreationDate"       = $_.WhenCreated
    }
}

Заключение

То, что мы продемонстрировали здесь, является лишь верхушкой айсберга с точки зрения того, что можно построить для отчета об инвентаризации. Есть много других полезных свойств, которые вы можете добавить в этот отчет. Продвигаясь дальше, вы можете встроить это в HTML-страницу, запланировать выполнение задачи на этой неделе или даже обернуть это другими инструментами, такими как Ansible.

PowerShell упрощает сбор всей необходимой информации в одном месте. После того, как вы проанализируете свою среду и определите, что вам нужно знать, создайте отчет в PowerShell, чтобы помочь вашей будущей способности проводить аудит вашей среды.


0 Comments

Ваш адрес email не будет опубликован. Обязательные поля помечены *