Вопрос или проблема
Можно ли запустить CrystalDiskInfo из командной строки/powershell?
этот скрипт выше очень поддерживает!
есть ли возможность разделить отчет на отдельные файлы для каждого ДИСКА (имя файла = серийный номер). Я пытался это сделать, но не смог разделить файл (сейчас каждый файл содержит ВСЕ значения CDi для дисков (кроме повторного вывода блока чисел, что удивительно)).
спасибо за помощь 🙂
# Определение пути для отчета
$ReportPath = "C:\share\_run\CDi CLi\reports"
# Создание директории для отчетов, если она не существует
if (-not (Test-Path $ReportPath)) {
New-Item -Path $ReportPath -ItemType Directory -Force | Out-Null
}
# Путь и выполнение CrystalDiskInfo
$cdiskinfo="C:\Program Files\CrystalDiskInfo"
& "$cdiskinfo\DiskInfo64.exe" /CopyExit
$s=gc "$cdiskinfo\DiskInfo.txt"
# Извлечение серийных номеров для создания папок
$serialMatches = $s | Select-String " Serial Number : (.+)$"
$serials = $serialMatches | ForEach-Object { $_.Matches.Groups[1].Value.Trim() }
# Получение текущего времени
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# Получение заголовочной информации (все до первых данных о диске)
$headerContent = [System.Collections.ArrayList]@()
$foundFirstDrive = $false
foreach ($line in $s) {
if ($line -match "^-{20,} \(\d+\) ") {
$foundFirstDrive = $true
break
}
$headerContent.Add($line) | Out-Null
}
# Обработка вывода для каждого диска
$currentSerial = $null
$currentContent = [System.Collections.ArrayList]@()
$isFirstDrive = $true
foreach ($line in $s) {
# Проверка, является ли это разделом нового диска
if ($line -match "^-{20,}$" -or $line -match "^-{20,} \(\d+\) ") {
# Если мы собрали данные для диска, сохраняем их
if ($currentSerial -and $currentContent.Count -gt 0) {
# Создание папки для диска
$driveFolder = Join-Path -Path $ReportPath -ChildPath $currentSerial
if (-not (Test-Path $driveFolder)) {
New-Item -Path $driveFolder -ItemType Directory -Force | Out-Null
}
# Сохранение содержимого с заголовком
$fileName = "CDi CLi - $currentSerial.txt"
$filePath = Join-Path -Path $driveFolder -ChildPath $fileName
# Добавление разделителя времени, если файл существует
if (Test-Path $filePath) {
"`n`n===========================================================" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"Report Date: $timestamp" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"===========================================================`n" | Out-File -FilePath $filePath -Encoding UTF8 -Append
}
# Комбинация заголовка и содержимого диска
$fullContent = [System.Collections.ArrayList]@()
$headerContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
$currentContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
# Запись в файл или добавление
if (Test-Path $filePath) {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8 -Append
} else {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8
}
}
# Сброс для следующего диска
$currentContent = [System.Collections.ArrayList]@()
$currentSerial = $null
}
# Добавление строки в текущее содержимое
$currentContent.Add($line) | Out-Null
# Проверка, содержит ли эта строка серийный номер
if ($line -match " Serial Number : (.+)$") {
$currentSerial = $matches[1].Trim()
}
}
# Сохранение содержимого последнего диска, если есть
if ($currentSerial -and $currentContent.Count -gt 0) {
$driveFolder = Join-Path -Path $ReportPath -ChildPath $currentSerial
if (-not (Test-Path $driveFolder)) {
New-Item -Path $driveFolder -ItemType Directory -Force | Out-Null
}
$fileName = "CDi CLi - $currentSerial.txt"
$filePath = Join-Path -Path $driveFolder -ChildPath $fileName
# Добавление разделителя времени, если файл существует
if (Test-Path $filePath) {
"`n`n===========================================================" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"Report Date: $timestamp" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"===========================================================`n" | Out-File -FilePath $filePath -Encoding UTF8 -Append
}
# Комбинация заголовка и содержимого диска
$fullContent = [System.Collections.ArrayList]@()
$headerContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
$currentContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
# Запись в файл или добавление
if (Test-Path $filePath) {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8 -Append
} else {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8
}
}
# Извлечение основной информации для отображения
$models=($s | select-string " Model : (.+)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() })
$firmwares=($s | select-string " Firmware : (.+)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() })
$healths=($s | Select-String " Health Status : (.+)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() })
$dletters=($s | Select-String " Drive Letter : (.+)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() })
$temps=($s | Select-String " Temperature : (.+)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() })
$feats=($s | Select-String " Features : (.+)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() })
# Создание и отображение объектов дисков
$Drives = for ($i=0;$i -lt $models.count;$i++) {
[PSCustomObject]@{
"Model"=$models[$i]
"Firmware"=$firmwares[$i]
"Health"=$healths[$i]
"Letter"=$dletters[$i]
"Temp"=$temps[$i]
"Features"=$feats[$i]
"Serial"=$serials[$i]
}
}
# Отображение информации о дисках в консоли
$Drives
Ответ или решение
Улучшение использования CrystalDiskInfo из командной строки или PowerShell
Вопросы, связанные с автоматизацией и управлением инструментарными утилитами через командную строку или PowerShell, становятся всё более актуальными в мире информационных технологий. CrystalDiskInfo — это популярная программа для мониторинга состояния жёстких дисков, предоставляющая детальную информацию о состоянии дисковых устройств. Она не только позволяет пользователям вручную проверять состояние жёстких дисков, но и через свои функциональные возможности может быть использована для автоматизации этого процесса. В данной статье мы рассмотрим, как можно усилить использование CrystalDiskInfo посредством PowerShell, включая решение задачи, связанной с раздельным хранением отчетов для каждого диска.
Теория
Ключевая задача, стоящая перед нами, заключается в автоматическом извлечении данных о дисках, их разбиение на отчеты для каждого устройства, и сохранение этих отчетов в отдельные файлы, где каждый файл именуется по серийному номеру диска. Такой подход обеспечивает упорядочивание и удобный доступ к данным, полученным от CrystalDiskInfo. Для решения этой задачи нам необходимо:
- Запуск CrystalDiskInfo с параметром
/CopyExit
, который создаёт текстовый файл DiskInfo.txt с информацией обо всех подключенных дисках. - Чтение и обработку содержимого этого файла, чтобы выделить серийные номера дисков.
- Разбиение информации так, чтобы данные о каждом диске находились в отдельном файле.
Пример
Приведенный ниже скрипт PowerShell демонстрирует практическое решение, отвечающее поставленным задачам:
# Указываем путь к директории, где будут сохраняться отчёты
$ReportPath = "C:\share\_run\CDi CLi\reports"
# Создаём директорию для отчётов, если она не существует
if (-not (Test-Path $ReportPath)) {
New-Item -Path $ReportPath -ItemType Directory -Force | Out-Null
}
# Определяем путь к утилите CrystalDiskInfo
$cdiskinfo="C:\Program Files\CrystalDiskInfo"
& "$cdiskinfo\DiskInfo64.exe" /CopyExit
$s = Get-Content "$cdiskinfo\DiskInfo.txt"
# Извлекаем серийные номера для создания папок
$serialMatches = $s | Select-String " Serial Number : (.+)$"
$serials = $serialMatches | ForEach-Object { $_.Matches.Groups[1].Value.Trim() }
# Получаем текущую метку времени
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# Обагощаем с методикой извлечения заголовка и деталей каждого диска
$headerContent = [System.Collections.ArrayList]@()
$foundFirstDrive = $false
foreach ($line in $s) {
if ($line -match "^-{20,} \(\d+\) ") {
$foundFirstDrive = $true
break
}
$headerContent.Add($line) | Out-Null
}
# Обработка информации по каждому устройству
$currentSerial = $null
$currentContent = [System.Collections.ArrayList]@()
$isFirstDrive = $true
foreach ($line in $s) {
if ($line -match "^-{20,}$" -or $line -match "^-{20,} \(\d+\) ") {
if ($currentSerial -and $currentContent.Count -gt 0) {
$driveFolder = Join-Path -Path $ReportPath -ChildPath $currentSerial
if (-not (Test-Path $driveFolder)) {
New-Item -Path $driveFolder -ItemType Directory -Force | Out-Null
}
$fileName = "CDi CLi - $currentSerial.txt"
$filePath = Join-Path -Path $driveFolder -ChildPath $fileName
if (Test-Path $filePath) {
"`n`n===========================================================" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"Report Date: $timestamp" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"===========================================================`n" | Out-File -FilePath $filePath -Encoding UTF8 -Append
}
$fullContent = [System.Collections.ArrayList]@()
$headerContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
$currentContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
if (Test-Path $filePath) {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8 -Append
} else {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8
}
}
$currentContent = [System.Collections.ArrayList]@()
$currentSerial = $null
}
$currentContent.Add($line) | Out-Null
if ($line -match " Serial Number : (.+)$") {
$currentSerial = $matches[1].Trim()
}
}
if ($currentSerial -and $currentContent.Count -gt 0) {
$driveFolder = Join-Path -Path $ReportPath -ChildPath $currentSerial
if (-not (Test-Path $driveFolder)) {
New-Item -Path $driveFolder -ItemType Directory -Force | Out-Null
}
$fileName = "CDi CLi - $currentSerial.txt"
$filePath = Join-Path -Path $driveFolder -ChildPath $fileName
if (Test-Path $filePath) {
"`n`n===========================================================" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"Report Date: $timestamp" | Out-File -FilePath $filePath -Encoding UTF8 -Append
"===========================================================`n" | Out-File -FilePath $filePath -Encoding UTF8 -Append
}
$fullContent = [System.Collections.ArrayList]@()
$headerContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
$currentContent | ForEach-Object { $fullContent.Add($_) | Out-Null }
if (Test-Path $filePath) {
$fullContent | Out-File -FilePath $filePath -Encoding UTF8 -Append
} else {
$fullContent | Out-File -Файл $filePath -Encoding UTF8
}
}
Применение
Данный скрипт предоставляет возможность улучшения взаимодействия с CrystalDiskInfo путем автоматизации процесса сбора и разбиения информации о дисках. Это может оказаться полезным в различных сценариях, таких как:
- Администрирование корпоративных сетей: В больших организациях, где используется множество дисков, важно иметь простые инструменты для мониторинга и анализа их состояния.
- Техническая поддержка и аудит: Позволяет техникам и аудиторам систем быстро получать актуальную информацию о каждом диске.
- Разработка программного обеспечения: Автоматическое получение и сохранение отчетов о состоянии дисков может быть интегрировано в процессы мониторинга и тестирования.
Заключение
Благодаря использованию PowerShell и возможностей CrystalDiskInfo, мы можем создавать гибкие решения для управления состоянием дисков. Это не только упрощает процессы мониторинга, но и открывает новые возможности для автоматизации рутинных задач, что в конечном итоге приводит к повышению общей эффективности и надежности ИТ-инфраструктуры.