Windows
banshee/windows-collection/windows/ssh/
services
The state and start mode of each service of a Windows, and the automatic services stopped, by SSH and PowerShell
by banshee1 installation2 versions
// The services of a Windows, by SSH: the state and the start mode of each one, stopped services included.
// A service is named by its service name ("wuauserv", "Spooler"), the same in every language of Windows,
// never by its display name, which is translated.
// Runs one PowerShell command that only reads Win32_Service (Name, State, StartMode), and in the registry
// the services whose automatic start is delayed (the value DelayedAutostart at 1 under
// HKLM\SYSTEM\CurrentControlSet\Services): Win32_Service does not serve that on every Windows from 2012 on.
// WMI writes State and StartMode in English words whatever the language of the system.
// "Automatic service stopped" raises on any service set to start automatically that is not running; a
// service in delayed automatic start is left to it, as Windows may stop it once its work is done.
// RemoteRegistry is left out of the default selection: Windows Server sets it to start automatically on a
// trigger, and stops it when it is idle.
need('protocol:ssh');
per('service', 'Services', array('ignore' => array('RemoteRegistry')));
output('state', 'text', array('label' => 'State', 'per' => 'service'));
output('start-mode', 'text', array('label' => 'Start mode', 'per' => 'service'));
watch.custom('auto-stopped', 'Automatic service stopped', array(
'help' => 'Critical when a service set to start automatically, without delay, is not running.',
));
// For a selection of services that must run, whatever their start mode.
watch.expect('stopped', 'Service stopped', 'state', array('critical' => array('running'), 'enabled' => false));
watch.missing('missing', 'Service missing', 'state');
$read = ssh.run("powershell -NoProfile -NonInteractive -Command \""
. "[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; "
. "ConvertTo-Json -Compress -Depth 4 -InputObject @{"
. "services = @(Get-CimInstance Win32_Service | Select-Object Name, State, StartMode); "
. "delayed = @(Get-ChildItem HKLM:\\SYSTEM\\CurrentControlSet\\Services"
. " | Get-ItemProperty -Name DelayedAutostart -ErrorAction SilentlyContinue"
. " | Where-Object DelayedAutostart -eq 1 | Select-Object PSChildName)}\"");
$answer = text.trim($read['output']);
if (list.count(text.match($answer, '^\{')) == 0) {
fail('misconfigured', 'PowerShell did not return the services', $answer . $read['errors']);
}
$read_services = json.read($answer);
// The name of a registry key is the service name.
$delayed = array();
foreach ($read_services['delayed'] as $key) {
$delayed[$key['PSChildName']] = true;
}
// State is "Running", "Stopped", "Start Pending", "Stop Pending", "Paused"...; StartMode "Auto", "Manual",
// "Disabled", "Boot" or "System". Both are given in lower case, words joined by "-": "start-pending".
// An automatic start with delay is given as "delayed".
$services = 0;
foreach ($read_services['services'] as $service) {
$name = $service['Name'];
$state = text.lower(text.join(text.words($service['State']), '-'));
$mode = text.lower($service['StartMode']);
if ($mode == 'auto' && list.has($delayed, $name)) {
$mode = 'delayed';
}
$services = $services + 1;
value('state', $state, $name);
value('start-mode', $mode, $name);
if ($mode == 'auto' && $state != 'running') {
watch.raise('auto-stopped', 'critical', $name . ' starts automatically and is ' . $state, $name);
}
}
if ($services == 0) {
fail('misconfigured', 'No service found in Win32_Service', $answer);
}