Последние записи.

Получение списка установленного ПО

Powershell Logo

На днях понадобилось оперативно собрать установленное ПО с клиентских компьютеров.
Времени для развертывания специального ПО не было, да и собственно самого ПО не было под рукой.
Почесав затылок и потыкав справку по работе с реестром из powershell получился скрипт который приведен чуть ниже.

Логика работы скрипта проста – подпихиваем файл hosts.txt, он в начале пытается пинговать хост, в случае успеха добавляет имя хоста в файл online.txt, в обратном случае в файл offline.txt.

Таким образом в файле offline.txt получается набор хостов которые не были протестированы по тем или иным причинам.

# get-Applications.ps1
# version 0.4

$erroractionpreference = "SilentlyContinue"

$hostFile = "hosts.txt"
$OnlineFile = "online.txt"
$OfflineFile = "offline.txt"

# Create files
New-Item -ItemType File $OnlineFile -Force
New-Item -ItemType File $OfflineFile -Force

# ping hosts
$colComputers = get-content $hostFile

foreach ($strComputer in $colComputers) {
  $ping = new-object System.Net.NetworkInformation.Ping
  $Reply = $ping.send($strComputer)
  if ($Reply.status –eq "Success") {
  # для русской версии необходимо заменить "Success" на "Ответ от"
  #if ($Reply.status –eq "Ответ от") {
    Add-Content $OnlineFile $strComputer
  } else {
    Add-Content $OfflineFile $strComputer
  }
$Reply = ""
}

$hosts = Get-Content $OnlineFile

# Создаем Excel книгу
$Excel = New-Object -Com Excel.Application
$Excel.visible = $True

# Начина
$Excel = $Excel.Workbooks.Add()
$wSheet = $Excel.Worksheets.Item(1)
$wSheet.Cells.item(1,1) = "HostName"
$wSheet.Cells.item(1,2) = "Verison"
$wSheet.Cells.Item(1,3) = "Publisher"
$wSheet.Cells.Item(1,4) = "UninstallString"
$wSheet.Cells.Item(1,5) = "Name"

$WorkBook = $wSheet.UsedRange
$WorkBook.Interior.ColorIndex = 8
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True

$intRow = 1
foreach ($remoteHost in $hosts) {
  $uninstallkey="Software\Microsoft\Windows\CurrentVersion\Uninstall"
  $keytype=[Microsoft.Win32.RegistryHive]::LocalMachine
  $remotebase=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($keytype,$remoteHost)

  $regkey=$remotebase.OpenSubKey($uninstallkey)

  $regkey.GetSubKeyNames() | foreach {
    $intRow++
    $wSheet.Cells.Item($intRow,1) = $remoteHost
    $wSheet.Cells.Item($intRow,2) = $remotebase.OpenSubKey("$uninstallkey\$_").GetValue("DisplayVersion")
    $wSheet.Cells.Item($intRow,3) = $remotebase.OpenSubKey("$uninstallkey\$_").GetValue("Publisher")
    $wSheet.Cells.Item($intRow,4) = $remotebase.OpenSubKey("$uninstallkey\$_").GetValue("UninstallString")
    $wSheet.Cells.Item($intRow,5) = $remotebase.OpenSubKey("$uninstallkey\$_").GetValue("DisplayName")
  }
}

$WorkBook.EntireColumn.AutoFit()

Windows 2008 R2 Core + IIS7.5 + PHP + MySQL

На днях возился со связкой Windows Server 2008 R2 Server Core + PHP + IIS7 + MySQL, смесь жуткая, но вполне работоспособная. Для того что бы в следующий раз не мучить себя вспоминая что и за чем идет написал небольшой мануал.

Постараюсь по шагам изложить все пройденные этапы.

1. Установка сервера в режиме Core.

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

2. Настройка сетевых карт.

По умолчанию настройки берутся с DHCP сервера, если таковой есть, но мы меняем их на статические адреса.

Получения списка существующих интерфейсов:

netsh interface ipv4 show interfaces

Вывод команды выглядит примерно так.

Idx     Met         MTU          State                Name
---  ----------  ----------  ------------  ---------------------------
  3           5        1500  connected     Local Area Connection
  1          50  4294967295  connected     Loopback Pseudo-Interface 1

Нужный нам интерфейс имеет имя Local Area Connection. Настраиваем для него статический адрес.

netsh interface ipv4 set address name=”Local Area Connection” source=static address= mask= gateway=

Для настраиваемого интерфейса добавляем DNS серверы.

netsh interface ipv4 add dnsserver name="Local Area Connection" address=

3. Выставляем время и дату, меняем имя сервера и при необходимости вводим его в домен.

Установка даты и времени.

Control timedate.cpl

Имя сервера меняем следующим образом:

netdom renamecomputer  /NewName:

Обязательная перезагрузка.

shutdown /r /t 0

Ввод в домен происходит так:

netdom join  /domain: /Userd: /passwordd: *

Обязательная перезагрузка.

shutdown /r /t 0

4. Настройка файервола
При необходимости использования RDP включаем его следующим образом:

cscript.exe %windir%\system32\SCRegEdit.wsf /ar 0

При необходимости разрешаем ICMP

netsh firewall set icmpsetting 8

Раз мы решили что у нас будет устанавливаться Mysql то разрешаем порт 3306 на файерволе

netsh firewall add portopening tcp 3306 "MySQL"

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

netsh advfirewall firewall set rule group="Remote Administration" new enable=yes

Если их необходимо детализировать то выбираем именно то что нам требуется

netsh advfirewall firewall set rule group="windows firewall remote management" new enable=yes
netsh advfirewall firewall set rule group="File and printer sharing" new enable=yes
netsh advfirewall firewall set rule group="Remote Event Log Management" new enable=yes
netsh advfirewall firewall set rule group="windows management instrumentation (wmi)" new enable=yes

6. Настройка службы обновлений
Просмотр текущих настроек

cscript.exe C:\Windows\System32\Scregedit.wsf /au /v

Автоматическое получение обновлений

cscript.exe C:\Windows\System32\Scregedit.wsf /au 4

Или отключение

cscript C:\Windows\System32\Scregedit.wsf /au 1

7. Отчеты об ошибках.
Я традиционно отключаю их следующей командой.

serverWerOptin /disable

или после проверки статуса

serverWerOptin /query

Можно автоматически отсылать детальные отчеты

serverWerOptin /detailed

Или отсылать итоговые отчеты

serverWerOptin /summary

8. Активация

cd C:\Windows\system32
cscript.exe slmgr.vbs –ato

Если вы используете MAK ключи

cd C:\Windows\system32
cscript.exe slmgr.vbs –ipk xxxx-xxxx-xxxx-xxxx-xxxx
cscript.exe slmgr.vbs –ato

9. Установка IIS 7.0 с поддержкой FastCGI

start /w pkgmgr /iu:IIS-WebServerRole;WAS-WindowsActivationService;WAS-ProcessModel;IIS-CGI

10. Установка PHP
Скачиваем последний пакет, желательно в виде архива, с официального сайта.
Распаковываем полученный архив в папку C:\PHP\, копируем файл c:\php\php.ini-recommended в c:\php\php.ini
В файле PHP.INI производим следующие изменения:

  • ищем строку с extension_dir и изменяем ее на extension_dir=»c:\php\ext»
  • раскомментировать: extension=php_mysql.dll
  • раскомментировать: Extension=php_gd.dll
  • сохранить то что получилось

11. Настройка PHP Handler в IIS

cd C:\Windows\system32\inetsrv
appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php\php-cgi.exe']
appcmd set config /section:system.webServer/handlers /+[name='PHP-FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\php\php-cgi.exe',resourceType='Either']

Добавляем обработку файлов php

cd C:\Windows\system32\inetsrv
appcmd set config "Default web site" /section:defaultDocument /enabled:true
appcmd set config "Default Web Site" /section:defaultDocument /+files.[value='index.php']

12. Установка MySQL
Скачиваем установочный пакет с официального сайта.
Установка производится из GUI-интерфейса, в типовом варианте и с последующей настройкой инстанции.

Собственно, если не вдаваться в подробности то получилась небольшая инструкция и если есть комментарии-вопросы-пожелания пишите.

Ответы на вопросы

Коллеги.

Получил пару писем с вопросами о том почему такой значительный перерыв в публикациях.

Отвечу на вопрос – пытаюсь доделать ремонт и времени катастрофически не хватает. Истрачено несколько ведер наличности, квартира сделана на 98 процентов, остались кое какие недоделки, уже возникли переделки…

Ребенок при принятии душа умудрился залить коридор водой, как результат придется перестилать ламинат :(

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

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

Жалко что нет сертификатов «Специалист по ремонту» а то я бы с удовольствием сходил сдал :)

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

Рассылка оповещений через powershell

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

Приступаем. Есть некий html-ный шаблон с картинкой внутри, он должен красиво приходить и соответственно выглядеть. Шаблон условно именуется template.html, а картинка к нему alert.png.

Рассылка должна выполняться при использовании BCC.

Пишем небольшой скрипт следующего содержания:

function Send-Message {
param([string]$ToAddress=(Throw ‘$ToAddress is required!’))

$SendingServer = "192.168.0.1"
$addresses = $ToAddress
if($ToAddress -isnot [Object[]]) {
$addresses = ([string]$ToAddress).Split(";")
}

$SMTPMessage = New-Object System.Net.Mail.MailMessage
$SMTPMessage.Body = Get-Content "X:\FULL\Path\TO\template.html"
$SMTPMessage.IsBodyHtml = $true
$SMTPMessage.From = "service.desk@example.com"
$SMTPMessage.Subject = "Уведомление о …"

foreach($singleAddress in $addresses) {
$SMTPMessage.BCC.Add($singleAddress)
# В случае если требуется выполнять отсылку с использованием TO необходимо раскомментировать строку ниже
#$SMTPMessage.TO.Add($singleAddress)
}

$Attachment = New-Object System.Net.Mail.Attachment "X:\FULL\Path\TO\alert.png"
$SMTPMessage.Attachments.Add($Attachment)

$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer
$SMTPClient.Send($SMTPMessage)
}
Send-Message ";;"

В строке Send-Message «< group1@example.com >;< group2@example.com >;< group3@example.com >» задается список групп которым необходимо выполнять отсылку.

Собственно и все.

Сборка данных о бэкапах старше Х дней

Powershell Logo
При аудите серверов БД возникла необходимость проверить состояние бэкапов примерно на сотне серверов MS SQL. Почесав затылок от перспективы «с пользой» провести массу времени, предпринял попытку вспомнить инструментарий который позволяет достичь поставленной задачи.

По первым линкам найденным в интернете выяснилось что некоторые продукты стоят денег, некоторые дают не ту информацию, некоторые дают совсем не ту информацию.

Выдохнул, включил в процесс голову и в процессе поисков наткнулся на SQL-скрипт для достижения нужного результата. Примерно за пять минут дописал к нему обертку из powershell-а и вот что получилось.

# get-backup-statistics.ps1
$servers = get-content servers.txt

foreach ($server in $servers) {
  Write-Output "======"
  Write-Output $server
  $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
  $SqlConnection.ConnectionString = "Server=$($server);Database=master;Integrated Security=True"
  $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
  $SqlCmd.CommandText = "SELECT database_name = sd.name, backup_finish_date, type
  FROM master.dbo.sysdatabases sd LEFT OUTER JOIN (
  SELECT bs.database_name, backup_finish_date, type = case type WHEN ‘D’ THEN ‘Database’
    WHEN ‘I’ THEN ‘Database Differential’
    WHEN ‘L’ THEN ‘Log’
    WHEN ‘F’ THEN ‘File or Filegroup’
  end, backup_size
  FROM msdb.dbo.backupset bs, (
  SELECT database_name,max_backup_finish_date = max(backup_finish_date)
    FROM msdb.dbo.backupset group by database_name) bs1
    WHERE bs.database_name = bs1.database_name
    AND bs.backup_finish_date = bs1.max_backup_finish_date ) bs3
    ON bs3.database_name = sd.name
    WHERE sd.name NOT IN (‘tempdb’)
    AND (backup_finish_date < getdate() -7 or backup_finish_date IS NULL
  )
  ORDER BY sd.name ASC, backup_finish_date DESC"

  $SqlCmd.Connection = $SqlConnection

  $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
  $SqlAdapter.SelectCommand = $SqlCmd

  $DataSet = New-Object System.Data.DataSet

  $SqlAdapter.Fill($DataSet)

  $SqlConnection.Close()
  $DataSet.Tables[0]
}

В приведенном примере из файла servers.txt берется список серверов БД и к ним выполняется запрос на получения списка баз данных для которых не выполнялись бэкапы более семи дней.