Привет, Habr!

Думаю всем системным администраторам известна довольна полезная утилита, которая позволяет на рабочем столе компьютеров в сети выводить информацию для них самих и для пользователей. Называется она Bginfo, была разработана Марком Русиновичем, входит в состав Sysinternals. Скачать утилиту и прочитать про нее можно на Learn.Microsoft

Внешний вид утилиты
Внешний вид утилиты
Пример отображения информации на рабочем столе
Пример отображения информации на рабочем столе

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

Итак приступим.

  1. Первое, что нам нужно сделать, это скачать саму утилиту и собрать файл конфигурации bgi. Распаковывем архив, получая одноименную папку с названием "BGInfo". В ней содержатся файлы самой утилиты 32 и 64-битных версий. Файл с описанием лицензионного соглашения. Сюда же сохраняем наш файл конфигурации с расширением .bgi, созданный через утилиту.

Итоговое содержимое папки
Итоговое содержимое папки
  1. Создаем папку "Install BGInfo", например в корне диска С:\ компьютера с которого будем производить установку на нужные нам компьютеры в сети. Копируем папку с утилитой и конфигом в эту папку.

  2. Создаем файл со списком имен удаленных компьютеров. Я назвал его "hosts.txt". Каждое имя пишем с новой строки. Если нужно закомментировать host, то просто добавляем решетку # перед именем. Сохраняем его в этой же папке "Install BGInfo".

    Содержимое файла hosts.txt
    Содержимое файла hosts.txt
  3. Создаем bat файл со следующим содержимым и сохраняем в ту же папку "Install BGInfo":

@cd/d "%~dp0"
@echo off
setlocal ENABLEDELAYEDEXPANSION
set "file=.\hosts.txt"
echo "Date: %DATE% time: %TIME%" > .\result_install_BGingo.csv
FOR /F %%x IN ('findstr /B /V /C:# %file%') DO (
ping %%x -n 1 | find "TTL=" > nul
if errorlevel 1 (
echo %%x offline
echo ***************************************************
echo %%x;offline >> .\result_install_BGingo.csv
) else (
echo install on %%x
xcopy .\BGInfo "\\%%x\c$\BGInfo" /e /y /i
echo reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Bginfo /t REG_SZ /d "C:\BGInfo\Bginfo64.exe C:\BGInfo\conf-bginfo.bgi /NOLICPROMPT /TIMER:0" /f > C:\reg.bat
xcopy "C:\reg.bat" "\\%%x\c$"
wmic /node:"%%x" process call create "C:\reg.bat"
TIMEOUT /T 5 /NOBREAK
del /f /q "C:\reg.bat"
del /f /q "\\%%x\c$\reg.bat"
echo reg files was deleted
echo ***************************************************
echo %%x;ok >> .\result_install_BGingo.csv
)
)
pause

В итоге мы получаем папку со следующим содержимым:

Содержимое папки Install BGInfo
Содержимое папки Install BGInfo

Суть скрипта следующая. Проходим по всем компьютерам в сети, указанным в файле hosts.txt. Пингуем хост и, если он доступен, то копируем папку "BGInfo" с утилитой в корень диска С:\ удаленного компьютера в сети. Создаем reg.bat для записи в реестр в ветку автозагрузки HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run переменной с именем Bginfo и ее значением "C:\BGInfo\Bginfo64.exe C:\BGInfo\conf-bginfo.bgi /NOLICPROMPT /TIMER:0". Копируем этот reg.bat в корень диска С:\ удаленного компьютера и запускаем его на исполнение. После отработки reg.bat на удаленном компьютере подчищаем за собой, удаляя сам батник на удаленной машине и у себя. Также после отработки нашего инсталятора мы получаем лог-файл "result_install_BGingo.csv" в котором отображены хосты с комментариями "offline" (хост недоступен) или "ок" (установка выполнена).

После всех приготовлений запускаем от имени администратора домена сам батник setuр_bginfo.bat и пьем кофеек, наблюдая за процессом установки.

Код проекта вы можете посмотреть и скачать на GitHub.

Комментарии (10)


  1. Sergey-S-Kovalev
    17.10.2022 16:21
    +1

    2022 год на дворе, в скриншотах Windows Vista и CMD-костылизация

    Пингующийся хост не гарантия, что он к себе по административной шаре пустит.

    Создавать папки в корне диска С:\ на каждый чих вместо служебных папок для этого предназначенных = варварство.

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

    Статью нужно доработать на кейс с рабочей группой, без домена :)


    1. vladimir-klp Автор
      17.10.2022 17:43
      +1

      Доброго времени суток. Спасибо за критику. Год хоть и 2022, а на некоторых госпредприятиях можно и Windows 98 встретить=)(скрины взяты прямо с сайта microsoft, уж не обессутьте).

      Это альтернативный вариант для тех, кому не хочется засорять контроллер домена лишними политиками, их настройками и грузить сеть постоянными обращениями к шаре, где лежит exe-шник с конфигом. Поставил один раз на нужные машины и забыл, до тех пор пока машину не переустановишь. Сами все подгрузят из своих недр, даже если сети не будет.

      А что касается диска С:, если это так принципиально в корень что-либо пихать лишнее, никто не мешает изменить путь и указать, например, Program files. Про допуск по административной шаре, то возможно не лишним будет проверка доступности, но обычно для администратора домена шара на машины пользователей доступна, а если нет, то тогда GPO точно ваш вариант.

      Для машин не в сети все также делается один раз:

      1. Копируем папку с bginfo на машину не в сети.

      2. Запускаем батник с одной строкой, который запишет переменную в реестр в ветку автозагрузки:

      reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Bginfo /t REG_SZ /d "C:\BGInfo\Bginfo64.exe C:\BGInfo\conf-bginfo.bgi /NOLICPROMPT /TIMER:0" /f


    1. aik
      17.10.2022 17:45
      +2

      в скриншотах Windows Vista и CMD-костылизация

      Лично у меня до сих пор в продакшне ХР имеется. Так что в висте ничего страшного нет.
      Ну и cmd тоже используется для не слишком сложных скриптов, где не нужно какую-то сложную логику реализовывать и данные парсить.


    1. OptimumOption
      18.10.2022 12:02

      Расшаривание корня диска, да еще и на запись - это вообще как и зачем?! За такие "костыли" надо бить по рукам, а ответственного за сие непотребство - макать головой в горячий капуччино!


      1. vladimir-klp Автор
        18.10.2022 20:51

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


  1. aik
    17.10.2022 17:43

    А зачем что-то устанавливать? Выложил на файловый сервер, засунул в логон-скрипт — и всё.


    1. vladimir-klp Автор
      17.10.2022 17:49

      Допустим это ноутбук, выдернули его из сети и всё, ничего не подгрузит. А так на нем все уже лежит и грузится без проблем локально через автозагрузку.


      1. aik
        17.10.2022 17:51
        +1

        Ну останется значит старое инфо на десктопе.


  1. delphersf
    18.10.2022 09:09

    DesktopInfo - думаю, лучшая замена bginfo.

    Еще есть O&O DeskInfo, но он не такой богатый возможностями.


    1. yellowmew
      19.10.2022 17:00

      [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
      [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
      
      $code = @'
          using System.Runtime.InteropServices;
          namespace Win32{
           public class Wallpaper{
              [DllImport("user32.dll", CharSet=CharSet.Auto)]
               static extern int SystemParametersInfo (int uAction , int uParam , string lpvParam , int fuWinIni) ;
               public static void SetWallpaper(string thePath){
                  SystemParametersInfo(20,0,thePath,3);
               }
          }
       }
      '@
      add-type $code
      
      
      $message=""
      $message+="ComputerName:" + $env:COMPUTERNAME + [Environment]::NewLine
      $message+="PROCESSOR_IDENTIFIER:" + $env:PROCESSOR_IDENTIFIER + [Environment]::NewLine
      $message+="IP Address(es): "+(Get-NetIPConfiguration).IPv4Address.IpAddress + [Environment]::NewLine
      
      $currentWallpaperPath = (Get-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name Wallpaper).Wallpaper
      $width = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width
      $height = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height
      $proposedSize = New-Object System.Drawing.Size ([int]$width,[int]$height)
      
      $fontStyle = "Calibri"
      $fontSize = 16
      
      $textfont = New-Object System.Drawing.Font ($fontStyle,$fontSize,[System.Drawing.FontStyle]::Regular)
      $textBrush = New-Object Drawing.SolidBrush ([System.Drawing.Color]::White)
      
      $bginfoPath = "$ENV:HOMEPATH\Pictures\bginfo.jpg"
      $wallpaper= "$ENV:HOMEPATH\Pictures\wallpaper_original.jpg"
      if (!(test-path $wallpaper)) { write-host "123"; Copy-Item $currentWallpaperPath $wallpaper }
      
      $srcBmp = [System.Drawing.Bitmap]::FromFile($wallpaper)
      $bmp = New-Object System.Drawing.Bitmap ($srcBmp,$width,$height)
      $graphics = [System.Drawing.Graphics]::FromImage($bmp)
      $graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAlias
      $srcBmp.Dispose()
      
      $messageSize = [System.Windows.Forms.TextRenderer]::MeasureText($message,$textfont,$proposedSize)
      $rec = New-Object System.Drawing.RectangleF (($width - $messageSize.Width - 20),20,($messageSize.Width + 20),$messageSize.Height)
      $graphics.DrawString($message,$textfont,$textBrush,$rec)
      
      $bmp.Save($bginfoPath,[System.Drawing.Imaging.ImageFormat]::Jpeg)
      
      Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name wallpaperstyle -Value 2
      Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name TileWallpaper -Value 0
      
      [Win32.Wallpaper]::SetWallpaper((Get-Item $bginfoPath).FullName)

      Пользуюсь только вот этим, на экран добавляется всё что может получить PoSH, в автозагрузке у пользователей powershell.exe bginfo.ps1

      Честно говоря, набросал по быстрому, потырив куски кода у AWS https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch-download.html