Windows Powershell - как повторно отображать состояния некоторых служб Windows только при их изменении? - PullRequest
2 голосов
/ 10 июня 2011

Я только начал с Powershell. У меня есть bat-файл, который просто запускает следующий скрипт PowerShell, который затем каждые 5 секунд повторно отображает состояние интересующих меня сервисов. Он работает хорошо (хотя я мог бы использовать некоторые указатели о том, как сделать это чище), за исключением того, что каждый раз, когда экран перекрашивается, появляется небольшое раздражающее мерцание. Итак, я хотел бы изменить это так, чтобы интервал ожидания составлял 1 секунду или 500 мс, но перерисовка выполняется только при изменении содержимого. В качестве альтернативы, если проще перекрасить экран DOS без каких-либо условий, не вызывая его мерцания, то я также был бы доволен этим решением. Также, пожалуйста, помогите мне очистить код. Я до сих пор боюсь функций, переменных и т. Д. В PowerShell, потому что PS часто кричит на меня, когда я пытаюсь использовать синтаксис и конструкции C-семейства / Python. PS чем-то отличается от Python, Java и т. Д., И я до сих пор не понял его философии.

# When you run this script, it will show a simple window with the status of the services;

# Do we want to XYZ as well?
# To assign $true value, use:
#PowerShell.exe .\ShowServices.ps1 -showXYZ:$true
#param([switch]$showXYZ=$false)
param([switch]$showXYZ=$true)

# Build a regex for services
$servicesRegex = "Microsoft.*|Network.*"
if ($showXYZ -eq $true) { $servicesRegex = $servicesRegex + "|XYZ.*" }

# Controlling the appearance of the window
$pshost = get-host
$pswindow = $pshost.ui.rawui

$newsize = $pswindow.buffersize
$newsize.height = 3000
$newsize.width = 50
$pswindow.buffersize = $newsize

$newsize = $pswindow.windowsize
$newsize.height = 10
$newsize.width = 50
$pswindow.windowsize = $newsize

$global:CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
#$global:ComputerName = gc env:computername
#$pswindow.WindowTitle = "Service statuses for {0} on {1}." -f $CurrentUser.Name, $ComputerName
$pswindow.WindowTitle = "Service statuses for {0}." -f $CurrentUser.Name

# Clear the screen once
clear

# Formatting details.
[int]$global:len1 = 35
[int]$global:len2 = 8
[int]$global:sleepInterval = 5 #seconds - I want this to be more frequent, but not annoying.

function printHeader
{
  Write-Host("") # Blank line
  [string]$line = "{0,-$global:len1}  {1,-$global:len2}" -f "Service Name", "Status"
  Write-Host $line
  Write-Host("_" * $global:len1 + "  " + "_" * $global:len2)
}

function printService($serviceObject)
{
  [string]$foreColor = "yellow" # Default color, if neither Stopped nor Running
  if ($serviceObject.status -eq "Stopped") {$foreColor = "red" }
  if ($serviceObject.status -eq "Running") {$foreColor = "green" }
  [string]$outStr = "{0,-$global:len1}  {1,-$global:len2}" -f $serviceObject.displayname, $serviceObject.status
  Write-Host $outStr -foregroundcolor $foreColor #-backgroundcolor white
}

# The meat of it.
while($true)
{
  printHeader
  Get-Service | Where-Object {$_.name -match $servicesRegex} | ForEach-Object { printService($_) }
  Start-Sleep -s $global:sleepInterval # Sleep x seconds
  clear
}

1 Ответ

3 голосов
/ 10 июня 2011

Попробуйте изменить последнюю часть вашего скрипта так:

# The meat of it.
$data = @()
while($true)
{
    $new = Get-Service | Where-Object {$_.name -match $servicesRegex}
    if (Compare-Object $data $new -Property Status) { 
        $data = $new
        clear
        printHeader
        $data | ForEach-Object { printService($_) }
    }
    Start-Sleep -s $global:sleepInterval # Sleep x seconds    
}
...