Как разрешить удалённый рабочий стол Windows через командную строку?
При конвейерной настройке компьютеров желательно, чтобы все операции были автоматизированы.
У нас автоматизировано многое, но всё ещё есть разная мелочь, которая либо включается/настраивается выборочно, либо не поддаётся автоматизации "с наскока".
Одна из таких операции – разрешение удалённого рабочего стола.
Включить поддержку удалённого рабочего стола очень легко:
REG ADD "%TGT%HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v "fDenyTSConnections" /t REG_DWORD /d 0 /f
Этот способ работает ещё с XP, и при этом ни перезагрузка, ни выход из системы не требуется.
Но если включен брандмауэр (а у нас он включен), порты остаются закрыты. При настройке через GUI, sysdm.cpl сразу разрешает соответствующие правила брандмауэра, причём по-умному – только для домена и частных сетей. В публичных сетях порт остаётся закрыт. Ещё включается "Remote Desktop - Shadow", но оно меня волнует мало.
Пара вариантов, найденных мной на этот счёт (MS Technet, Пример в справке netsh (см. tooltip)) делают не то же самое: первый включает только правило для текущей сети (даже если она публичная), второй – для всех (в том числе для публичных).
Первое, что я подумал сделать – модифицировать второй вариант:
netsh advfirewall firewall set rule group="remote desktop" profile=private,domain new enable=yes
но, как часто бывает с утилитами Microsoft, самый прямой, простой и очевидный способ не работает:
Group cannot be specified with other identification conditions.
Кроме того, как я выяснил позже, названия групп зависят от языка ОС :( Кстати, второй по простоте и очевидности вариант тоже не работает:
netsh advfirewall firewall set rule name=all localport=3389 dir=in profile=private,domain new enable=yes
- просто выводит справку, как будто я совсем накосячил с синтаксисом. Как я выяснил методом тыка, ему не нравится name=all.
Забавно (и печально), но в условиях выбора правил обязательно указывать имя правила или группы. Причём, чтобы была возможность показать все правила, используется специальное название – all. Однако, это название работает только для netsh advfirewall firewall show rule name=all. Для set rule это запрещено.
Иногда у меня подозрение, что в MS есть специально обученные люди, которые проверяют, чтобы интерфейс командной строки был сложным и запутанным. Я почти ударил головой по столу, но пока не сдаюсь.
Казалось бы, в чём проблема указать 4 имени для правил? В том, что, во-первых, имена могут отличаться в разных версиях Windows, а во-вторых, они зависят от языка. Кроме того, по умолчанию правила для публичных и частных сетей объединены (при включении в GUI они разделяются), и в Windows 7 нет правила для UDP. Т.е. придётся писать кучу вариантов для разных версий ОС и следить, чтобы при обновлениях ничего не поломалось.
Я также думал делать разбор вывода netsh advfirewall firewall show rule name=all и искать по номеру порта (и в этот раз я не удивился, когда узнал, что для show нельзя указывать ни group, ни номер локального порта). Но выводимый текст зависит от языка, так что опираться можно только на цифры и разделители, и надеяться, что такое число не встретится больше ни в одном поле ни одного действующего правила (в правилах по умолчанию – не встречается). Да ещё и структура выводимой информации весьма сложна для разбора, так пока что я отложил этот вариант.
Пока решение – добавить требуемые правила:
REG ADD "%TGT%HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v "fDenyTSConnections" /t REG_DWORD /d 0 /f "%SystemRoot%\system32\netsh.exe" advfirewall firewall add rule name="Remote Desktop - User Mode (TCP-In)" dir=in action=allow program="%%SystemRoot%%\system32\svchost.exe" service="TermService" description="Inbound rule for the Remote Desktop service to allow RDP traffic. [TCP 3389] added by LogicDaemon's script" enable=yes profile=private,domain localport=3389 protocol=tcp "%SystemRoot%\system32\netsh.exe" advfirewall firewall add rule name="Remote Desktop - User Mode (UDP-In)" dir=in action=allow program="%%SystemRoot%%\system32\svchost.exe" service="TermService" description="Inbound rule for the Remote Desktop service to allow RDP traffic. [UDP 3389] added by LogicDaemon's script" enable=yes profile=private,domain localport=3389 protocol=udp
Но я понимаю, что этот вариант – весьма даже костыль, и поэтому скромно спрашиваю, что делать, на superuser.
P.S.1 Кстати, для тех, кто думает, что если уж парсить, то лучше читать реестр (конкретно – ветку HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules) – облом: в русской Windows имена правил записаны как @FirewallAPI.dll,номер ресурса. Насколько я понимаю, доступного способа читать в командной строке ресурсы из DLL нету :(
P.S.2 Если адепты PowerShell подскажут, как быстро и безболезненно выполнить фокус с правилами, возможно, я тоже стану адептом. hint: enable-netfirewallrule не работает в Windows 7. Цель следующая: фаервол настроен по умолчанию (сбросьте настройки), надо привести его в состояние, как после включения удалённого рабочего стола в GUI (если уже включен, то выключите, примените, включите).