-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSync-ComputerState.ps1
140 lines (126 loc) · 7.32 KB
/
Sync-ComputerState.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<#
.SYNOPSIS
Включение или выключение целевого компьютера.
.DESCRIPTION
Скрипт включает широковещательным магическим пакетом целевой компьютер
или выключает его, в зависимрсти от состояния доступности исходнного
компьютера. Так же возможна дополнительная проверка другого участника
для исключения ложного срабатывания при сбои сети.
.PARAMETER Source
Исходный компьютер для получения состояния.
.PARAMETER Target
Целевой компьютер для установки состояния.
.PARAMETER Check
Дополнительный компьютер для проверки.
.PARAMETER MAC
MAC адрес целевого компьютера для отправки мачического пакета.
.PARAMETER Try
Количество попыток проверки доступности каждого узла, а так же
количество отправляемых магических пакетов.
.PARAMETER Port
Порт получателя магтческих пакетов.
.INPUTS
Вы не можете передавать в скрипт объекты по коневееру.
.OUTPUTS
Скрипт не генерит возвращаемые объекты.
.NOTES
Версия: 0.1.2
Автор: @ViPiC
#>
[CmdletBinding()]
Param (
[string]$Source,
[string]$Target,
[string]$Check,
[string]$MAC,
[ValidateRange(1, 99)]
[int]$Try = 3,
[ValidateRange(1, 65535)]
[int]$Port = 9
);
$isCheckOnline = $true; $isSourceOnline = $true; $isTargetOnline = $true;
# Получаем информацию об ip адресах дополнительного компьютера и проверяем доступность
$ChecksIPv4 = @(); $ChecksIPv6 = @();
if ($Check) {
$List = @($Check);
if ([IPAddress]::TryParse($List[0], [ref][IPAddress]::Loopback)) {
if (($List[0].IndexOf(".") -ge 0)) { $ChecksIPv4 = @($List[0]); };
if (($List[0].IndexOf(":") -ge 0)) { $ChecksIPv6 = @($List[0]); };
}
else {
$Resolve = (Resolve-DnsName -Name $List[0] -ErrorAction "Ignore" | Where-Object "Section" -EQ "Answer");
if ($Resolve) { foreach ($CheckIPv4 in $Resolve.IP4Address) { $ChecksIPv4 += $CheckIPv4; }; };
if ($Resolve) { foreach ($CheckIPv6 in $Resolve.IP6Address) { $ChecksIPv6 += $CheckIPv6; }; };
};
$isPassIPv4 = (($ChecksIPv4.Count -gt 0) -and (Test-Connection -ComputerName $ChecksIPv4 -Count $Try -Quiet -ErrorAction "Ignore"));
$isPassIPv6 = (($ChecksIPv6.Count -gt 0) -and (Test-Connection -ComputerName $ChecksIPv6 -Count $Try -Quiet -ErrorAction "Ignore"));
$isCheckOnline = ($isPassIPv4 -or $isPassIPv6);
};
# Получаем информацию об ip адресах исходного компьютера и проверяем доступность
$SourcesIPv4 = @(); $SourcesIPv6 = @();
if ($Source -and $isCheckOnline) {
$List = @($Source);
if ([IPAddress]::TryParse($List[0], [ref][IPAddress]::Loopback)) {
if (($List[0].IndexOf(".") -ge 0)) { $SourcesIPv4 = @($List[0]); };
if (($List[0].IndexOf(":") -ge 0)) { $SourcesIPv4 = @($List[0]); };
}
else {
$Resolve = (Resolve-DnsName -Name $List[0] -ErrorAction "Ignore" | Where-Object "Section" -EQ "Answer");
if ($Resolve) { foreach ($SourceIPv4 in $Resolve.IP4Address) { $SourcesIPv4 += $SourceIPv4; }; };
if ($Resolve) { foreach ($SourceIPv6 in $Resolve.IP6Address) { $SourcesIPv6 += $SourceIPv6; }; };
};
$isPassIPv4 = (($SourcesIPv4.Count -gt 0) -and (Test-Connection -ComputerName $SourcesIPv4 -Count $Try -Quiet -ErrorAction "Ignore"));
$isPassIPv6 = (($SourcesIPv6.Count -gt 0) -and (Test-Connection -ComputerName $SourcesIPv6 -Count $Try -Quiet -ErrorAction "Ignore"));
$isSourceOnline = ($isPassIPv4 -or $isPassIPv6);
};
# Получаем информацию об ip адресах целевого компьютера и проверяем доступность
$TargetsIPv4 = @(); $TargetsIPv6 = @();
if ($Target -and $isCheckOnline) {
$List = @($Target);
if ([IPAddress]::TryParse($List[0], [ref][IPAddress]::Loopback)) {
if (($List[0].IndexOf(".") -ge 0)) { $TargetsIPv4 = @($List[0]); };
if (($List[0].IndexOf(":") -ge 0)) { $TargetsIPv4 = @($List[0]); };
}
else {
$Resolve = (Resolve-DnsName -Name $List[0] -ErrorAction "Ignore" | Where-Object "Section" -EQ "Answer");
if ($Resolve) { foreach ($TargetIPv4 in $Resolve.IP4Address) { $TargetsIPv4 += $TargetIPv4; }; };
if ($Resolve) { foreach ($TargetIPv6 in $Resolve.IP6Address) { $TargetsIPv6 += $TargetIPv6; }; };
};
$isPassIPv4 = (($TargetsIPv4.Count -gt 0) -and (Test-Connection -ComputerName $TargetsIPv4 -Count $Try -Quiet -ErrorAction "Ignore"));
$isPassIPv6 = (($TargetsIPv6.Count -gt 0) -and (Test-Connection -ComputerName $TargetsIPv6 -Count $Try -Quiet -ErrorAction "Ignore"));
$isTargetOnline = ($isPassIPv4 -or $isPassIPv6);
};
# Выполняем действие над целевым компьютером
if ($isCheckOnline) {
# Включаем целевой компьютер
if (-not($isTargetOnline) -and $isSourceOnline -and $MAC) {
# Готовим магический пакет
$ChainSync = [byte[]](, 0xFF * 6); # цепочка синхронизации
$MacAddress = $MAC -split "-" | ForEach-Object { [byte]("0x" + $PSItem) };
$MagicPacket = $ChainSync + $MacAddress * 16;
# Получаем список всех доступных интерфейсов для отправки
$Interfaces = [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | Where-Object {
$PSItem.NetworkInterfaceType -ne [System.Net.NetworkInformation.NetworkInterfaceType]::Loopback -and
$PSItem.OperationalStatus -eq [System.Net.NetworkInformation.OperationalStatus]::Up
};
# Последовательно отправляем магические пакеты в доступные интерфейсы
foreach ($Interface in $Interfaces) {
$TargetIpAddress = [System.Net.IPAddress]::Broadcast;
$LocalIpAddress = $Interface.GetIPProperties().UnicastAddresses | Where-Object {
$PSItem.Address.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork
} | Select-Object -First 1 | Select-Object -ExpandProperty "Address";
$TargetEndPoint = [System.Net.IPEndPoint]::new($TargetIpAddress, $Port);
$LocalEndPoint = [System.Net.IPEndPoint]::new($LocalIpAddress, 0);
$UdpClient = [System.Net.Sockets.UdpClient]::new($LocalEndPoint);
for ($i = 0; $i -lt $Try; $i++) {
$UdpClient.Send($MagicPacket, $MagicPacket.Length, $TargetEndPoint) | Out-Null;
};
$UdpClient.Dispose();
};
};
# Выключаем целевой компьютер
if (-not($isSourceOnline) -and $isTargetOnline) {
if ($Target) { Stop-Computer -ComputerName $Target -Force; }
else { Stop-Computer -Force; };
};
};