пятница, 25 апреля 2014 г.

Отключение выбора пользователя и ввода пароля при запуске Windows

Если вы пользуетесь ПК дома и вам неудобно каждый раз выбирать пользователя и вводить пароль, то можно воспользоваться следующей настройкой ОС Windows:

1. Выполните команду "control userpasswords2";
2. В появившемся окне снимите галочку "Требовать ввод имени пользователя и пароля" и нажмите "Применить";


3. В окне "Автоматический вход в систему" введите имя пользователя, под которым будет осуществляться логон в систему, и пароль с подтверждением.

Чтобы вернуться к первоначальному способу входа в ОС, установите обратно галочку "Требовать ввод имени пользователя и пароля".

четверг, 24 апреля 2014 г.

Установка ограничений для ОС Windows по использованию оперативной памяти и ядер процессора

Иногда необходимо протестировать работу ПО в условиях ограничения физических ресурсов. Для этого не нужно доставать модули памяти или менять процессор, достаточно сделать следующие настройки:

1. Выполняем команду "msconfig";
2. Переходим в закладку "Загрузка", затем нажимаем "Дополнительные параметры";
3. Ставим галочки: "Число процессоров", "Максимум памяти" и устанавливаем необходимые ограничения;
4. После перезагрузки системы ваша Windows будет использовать только тот объём ресурсов, который вы указали в настройках:


Данный функционал доступен во всех версиях ОС Windows начиная с Vista.

среда, 16 апреля 2014 г.

VBScript: реализация повышения уровня привилегий при запуске скрипта

При написании vbs-скрипта для повседневного использования часто возникает необходимость в выполнении команд с повышенным уровнем привилегий. В самом простом варианте можно запускать скрипт с помощью "runas" или из другой программы, которая, в свою очередь, уже была выполнена с повышением привилегий. Но лучше пойти другим путём.
Ниже приведен пример реализации обработки контроля учётных записей в коде самого скрипта:

Const DQ = """", HKLM = &H80000002, KQV = &H1, KSV = &H2
SET colOS = GetObject("winmgmts:\root\cimv2").ExecQuery("Select * from Win32_OperatingSystem")
FOR EACH oOS IN colOS
 strOSLong = oOS.Version
NEXT
IF Left(strOSLong, 1) > "5" THEN
    IF NOT isAdminRights THEN
  SET oShellApp = CreateObject("Shell.Application")
  oShellApp.ShellExecute WScript.FullName, DQ & WScript.ScriptFullName & DQ, "", "runas", 1
  WScript.Quit
    END IF
END IF
''''''''''Begin of code''''''''''''''''''''''''''''''
'
'
'
''''''''''End of code''''''''''''''''''''''''''''''''
FUNCTION isAdminRights()
 SET oReg = GetObject("winmgmts:root\default:StdRegProv")
 strKey = "System\CurrentControlSet\Control\Session Manager"
 intErrNum = oReg.CheckAccess(HKLM, strKey, KQV + KSV, flagAccess)
 isAdminRights = flagAccess
END FUNCTION

В данном примере происходит проверка на наличие необходимых прав доступа к ветке реестра "System\CurrentControlSet\Control\Session Manager". В случае их отсутствия, скрипт сам себя перезапускает с уже повышенными привилегиями. Вам остаётся лишь добавить код в обозначенном месте.

вторник, 15 апреля 2014 г.

VBScript: скрытие проблемных обновлений Windows в домене с помощью Group Policy

Скрипт позволяет массово скрывать определённые обновления при выполнении на каждом компьютере с помощью групповой политики домена. Администратору необходимо только корректно задать номера KB в начальном массиве.

DIM hideupdates(2)
hideupdates(0) = "KB2925418"
hideupdates(1) = "KB2930275"
hideupdates(2) = "KB2929961"
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SET updateSession = createObject("Microsoft.Update.Session")
SET updateSearcher = updateSession.CreateupdateSearcher()
SET searchResult = updateSearcher.Search("IsHidden=0 and IsInstalled=0 and Type='Software'")
FOR i = 0 TO searchResult.Updates.Count-1
 SET update = searchResult.Updates.Item(i)
 FOR j = LBound(hideupdates) TO UBound(hideupdates)
  IF instr(1, update.Title, hideupdates(j), vbTextCompare) <> 0 THEN
   update.IsHidden = TRUE
  END IF
 NEXT
NEXT

Перед использованием сделайте следующие изменения скрипта:
1. Задайте количество ячеек массива в первой строке: hideupdates(0 - 1 запись, 1 - 2 записи, 2 - 3 записи и т.д.).
2. Пропишите свои номера обновлений в ячейках массива так же, как сделано в скрипте, лишние удалите или закомментируйте.
 3. Добавьте vbs-файл в политики домена для выполнения во время загрузки ОС.

Данный скрипт в групповых политиках удобно сочетать с фильтром WMI или другим скриптом по определению версии ОС Windows.

понедельник, 14 апреля 2014 г.

Сбрасываем RDP сессию удалённо

Если при попытке подключения к серверу по протоколу RDP вы видите окошко: "The terminal server has exceeded the maximum number of allowed connections" - это означает превышение максимально допустимого числа соединений(до 2 для серверов Windows по умолчанию). Происходит это из-за того, что пользователи забывают завершить свой сеанс и просто отключаются от сервера.


Для того, чтобы убить сессию на удалённом компьютере, выполните следующие команды:

1. Для начала нужно выполнить запрос и узнать какие сессии в данный момент активны на удалённом сервере:

query session /server:servername_or_IP"

2. Затем осуществляем сброс сессии, используя её идентификатор (ID):

reset session ID /server:servername_or_IP

servername_or_IP - имя или IP адрес удалённого хоста.

Выполнять данные команды необходимо только под пользователем, являющимся локальным администратором на удалённой машине!

пятница, 11 апреля 2014 г.

VBScript: поиск и удаление устаревших учётных записей компьютеров в Active Directory

Скрипт предназначен для поиска в Active Directory учётных записей персональных компьютеров, которые по каким либо причинам давно не синхронизировались с доменом.
Чтобы начать работу, необходимо прописать начальные значения следующих переменных:

FQDN - имя LDAP вашего домена или нужной ветки;
intTimeLimit - считать записи устаревшими, если они не синхронизировались более данного количества дней назад;
flagDelete - может принимать два значения:
    TRUE - выполнять удаление при поиске учётных записей;
    FALSE - режим чтения, только отображать информацию.

ON ERROR RESUME NEXT
FQDN = "DC=mydomain,DC=corp" 'Input your Fully Qualified Domain Name or LDAP path to subtree
intTimeLimit = 360  'Time limit in number of days
flagDelete = FALSE  'Flag for deleting old computers. FASLE = find only, TRUE = find and DELETE!!!
Const ADS_SCOPE_SUBTREE = 2
SET objConnection = CreateObject("ADODB.Connection")
SET objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
SET objCommand.ActiveConnection = objConnection
objCommand.CommandText = "Select Name,distinguishedName,lastLogon from " & "'LDAP://" & FQDN & "' where objectClass='computer'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
SET objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
DO UNTIL objRecordset.EOF
 objLogon = objRecordSet.Fields("lastLogon")
 intLogonTime = objLogon.HighPart * (2^32) + objLogon.LowPart
 intLogonTime = intLogonTime / (60 * 10000000)
 intLogonTime = intLogonTime / 1440
 IF intLogonTime + #1/1/1601# < Now - intTimeLimit THEN
  Wscript.Echo "Computer Name: " & objRecordSet.Fields("Name").Value
  Wscript.Echo "Path: " & objRecordSet.Fields("distinguishedName").Value
  WScript.Echo "Approx last logon timestamp: " & intLogonTime + #1/1/1601#
  Wscript.Echo "=========================================================" 
  IF flagDelete THEN
   SET objComputer = GetObject("LDAP://" & objRecordSet.Fields("distinguishedName").Value)
   objComputer.DeleteObject(0)
  END IF
 END IF
    objRecordSet.MoveNext
LOOP

Особенно внимательным нужно быть с переменной "intTimeLimit"!!!
Задание слишком малого значения может привести к потери практически всех компьютерных аккаунтов!!!

Для удобства скрипт лучше запускать с помощью "cscript.exe".

среда, 9 апреля 2014 г.

VBScript: автоматизация поиска и установки обновлений Windows без участия пользователя

Нижеприведенный скрипт позволяет автоматизировать процесс установки обновлений Windows на только что проинсталлированную систему:

'''''''''''''''''''''''''''''''''''''     Auto Update VBScript for Windows      '''''''''''''''''''''''''''''''
'''
ON ERROR RESUME NEXT
''' Constants and variables
Attempt = 3                'Number of attempts to get updates
Const PauseTime = 15    'Number of minutes for pause between searching
Const HKEY_LOCAL_MACHINE = &H80000002
strUserName = "WinUpdate"
strFullName = "Windows Update Account"
strDescr = "Windows Update Account for AutoLogon"
strPassword = "1234567"
strGroupSID = "S-1-5-32-544"  'Well Known SID of the Administrators group
''' Detection OS and elevate privileges
SET colOS = GetObject("winmgmts:\root\cimv2").ExecQuery("Select * from Win32_OperatingSystem")
FOR EACH oOS IN colOS
    strOSLong = oOS.Version
NEXT
IF Left(strOSLong, 1) > "5" AND WScript.Arguments.length = 0 THEN
 SET oShellApp = CreateObject("Shell.Application")
 oShellApp.ShellExecute "cscript.exe", Chr(34) & WScript.ScriptFullName & Chr(34) & " uac", "//NoLogo //S", "runas", 1
 WScript.Quit
END IF
''' Copy script to Temp folder and restart them
SET WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = WshNetwork.ComputerName
SET WshShell = WScript.CreateObject("WScript.Shell")
SET objFSO = CreateObject("Scripting.FileSystemObject")
IF NOT objFSO.FileExists(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs") THEN 
 IF NOT objFSO.FolderExists(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp") THEN 
  objFSO.CreateFolder(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp")
 END IF
 objFSO.CopyFile Wscript.ScriptFullName, WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs", TRUE
 WshShell.Run "cscript //NoLogo //S " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs"
 WScript.Quit
ELSE
 IF Wscript.ScriptFullName <> WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs" THEN
  WshShell.Run "cscript //NoLogo //S " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs"
  WScript.Quit
 END IF
''' Preparing user for autologon
 WScript.Echo "Setup user....................................................................."
''' Check if local account already exists
 intExists = 0
 SET objSystem = GetObject("WinNT://" & strComputer)
 objSystem.Filter = Array("user")
 FOR EACH objUser IN objSystem
  IF objUser.Name = strUserName THEN
   intExists = 1
  END IF
 NEXT
'''  Finging correct title of admins group
 strGroupName = GetGroupName(strComputer, strGroupSID)
'''  Creating the user autoupdate
 IF intExists = 0 THEN
  SET objUser = objSystem.Create("user", strUserName)
  objUser.FullName = strFullName
  objUser.Description = strDescr
  objUser.SetPassword strPassword
  objUser.SetInfo
  SET objGroup = GetObject("WinNT://" & strComputer & "/" & strGroupName & ",group")
'''  Adding autoupdate to the admins group
  SET objUser = GetObject("WinNT://" & strComputer & "/" & strUserName & ",user")
  objGroup.Add(objUser.ADsPath)
 END IF
'''  Deleting the AutoLogonCount
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "AutoLogonCount"
 oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
'''  Setting forceAutoLogon to TRUE
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "ForceAutoLogon"
 strValue = "1"
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
''' Setting the default username to be the same as strUserName
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "DefaultUserName"
 strValue = strUsername
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Setting the default password to be same as strPassword
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "DefaultPassword"
 strValue = strPassword
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Setting AutoAdminLogon to TRUE
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "AutoAdminLogon"
 strValue = "1"
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Setting the default login domain to be the local machine
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "DefaultDomainName"
 strValue = strComputer
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
 '''  Setting AutoRun after reboot
 IF Left(strOSLong, 1) > "5" THEN
  WshShell.Run "%WINDIR%\system32\SCHTASKS.exe /Create /TN Autoupdater /TR ""cscript " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs //S //NoLogo"" /F /RL HIGHEST /IT /SC ONLOGON /RU " & strComputer & "\" & strUserName, 0
 ELSE
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
  strValueName = "autoupdate"
  strValue = "cscript //NoLogo //S " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs"
  oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
 END IF
'''  Searching Updates
 WScript.Echo "Searching Updates:"
 DO
  Attempt = Attempt - 1
  WScript.Echo "Searching in progress...           (Number of remaining attempts is " & Attempt & ")"
  SET updateSession = createObject("Microsoft.Update.Session")
  SET updateSearcher = updateSession.CreateupdateSearcher()
  SET searchResult = updateSearcher.Search("IsHidden=0 and IsInstalled=0 and Type='Software'")
  IF searchResult.Updates.Count <> 0 OR Attempt = 0 THEN EXIT DO
  WScript.Echo "Waiting for " & PauseTime & " minutes before next searching..."
  WshShell.Run "%WINDIR%\system32\wuauclt.exe /detectnow", 0
  WScript.Sleep PauseTime*60000
 LOOP WHILE Attempt > 0
''' Downloading Updates
 IF Attempt > 0 THEN 'If there are updates for installing
  IF searchResult.Updates.Count <> 0 THEN
   WScript.Echo searchResult.Updates.Count & " updates are available."
  END IF
  flagDownload = 0
  FOR i = 0 To searchResult.Updates.Count-1
   SET update = searchResult.Updates.Item(i)
   IF update.IsDownloaded = FALSE THEN
    SET updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
    updatesToDownload.Add(update)
    IF updatesToDownload.Count = 1 AND flagDownload = 0 THEN
     WScript.Echo "Downloading Updates............................................................"
     flagDownload = 1
    END IF
    WScript.Echo "Downloading: " & update.Title
    SET downloader = updateSession.CreateUpdateDownloader() 
    downloader.Updates = updatesToDownload
    downloader.Download()
   END IF
  NEXT
''' Installing Updates
  WScript.Echo "Installing Updates............................................................."
  FOR i = 0 To searchResult.Updates.Count-1
   SET update = searchResult.Updates.Item(i)
   SET updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")
   updatesToInstall.Add(update)  
   WScript.Echo "Installing: " & update.Title
   SET installer = updateSession.CreateUpdateInstaller()
   installer.Updates = updatesToInstall
   SET installationResult = installer.Install()
   IF ((installationResult.RebootRequired = TRUE) OR (Err.Number <> 0)) THEN
    WScript.Echo "Reboot after 3 seconds for complete installation of update!"
    WScript.Sleep 3000
    SET objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Shutdown)}!\\" & strComputer & "\root\cimv2")
    SET colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    FOR EACH objOperatingSystem IN colOperatingSystems
     objOperatingSystem.Reboot()
    NEXT
   END IF
  NEXT
 ELSE 'If no more updates
  WScript.Echo "Cleaning script information..."
'''  Setting AutoAdminLogon to FALSE
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
  strValueName = "AutoAdminLogon"
  strValue = "0"
  oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Deleting forceAutoLogon
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
  strValueName = "ForceAutoLogon"
  oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
'''  Deleting AutoRun after reboot
  IF Left(strOSLong, 1) > "5" THEN
   WshShell.Run "%WINDIR%\system32\SCHTASKS.exe /Delete /TN Autoupdater /F", 0
  ELSE
   SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
   strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
   strValueName = "autoupdate"
   oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
  END IF
'''  Deleting the default password to be same as strPassword
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
  strValueName = "DefaultPassword"
  oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
'''  Deleting autoupdate user
  objSystem.Delete "user", strUserName
'''  Deleting temporary script file
  objFSO.DeleteFile(Wscript.ScriptFullName)
  SET fc = objFSO.GetFolder(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp").Files
  IF 0 = fc.Count THEN
   objFSO.DeleteFolder(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp")
  END IF
 END IF
'''Finishing
 WScript.Echo "Complete, computer reboots after 5 seconds!"
 WScript.Sleep 5000
 SET objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Shutdown)}!\\" & strComputer & "\root\cimv2")
 SET colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
 FOR EACH objOperatingSystem IN colOperatingSystems
  objOperatingSystem.Reboot()
 NEXT
END IF
''''''''''''''''''Function for obtaining name of local Administrators group''''''''''''''''
FUNCTION GetGroupName(sComputer, sGroupSID)
 DIM oGroupAccounts, oGroupAccount
 SET oGroupAccounts = GetObject("winmgmts://" & sComputer & "/root/cimv2").ExecQuery("Select Name from Win32_Group" & " WHERE Domain = '" & sComputer & "' AND SID = '" & sGroupSID & "'")
 FOR EACH oGroupAccount IN oGroupAccounts
  GetGroupName = oGroupAccount.Name
 NEXT
END FUNCTION
''''''''''''''''''

Принцип работы следующий: Скрипт копирует себя в папку Temp и перезапускается с повышенными привилегиями в случае ОС Windows Vista и выше. Также, для автоматизации работы, создает пользователя WinUpdate и настраивает для него автоматический вход в систему, прописывается в автозапуск. Далее происходит поиск и установка обновлений, перезагрузка, и снова поиск и установка. Это длится до тех пор, пока скрипт не перестает находить новые обновления. Когда все попытки поиска исчерпаны, скрипт очищает все сделанные изменения в ОС и удаляется из папки Temp.
Управлять поиском можно с помощью переменной Attempt(количество предпринимаемых попыток поиска обновлений) и константы PauseTime(длина паузы между попытками поиска в минутах).
Скачать готовый vbs-файл можно по данной ссылке.

вторник, 8 апреля 2014 г.

VBScript: установка пароля локального Администратора

Данный скрипт будет полезен для смены пароля локального Администратора на компьютерах в домене. Поскольку аккаунт идентифицируется с помощью SID, код будет работать для любых локализаций Windows.


SET WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = WshNetwork.ComputerName
SET objSystem = GetObject("winmgmts://" & strComputer & "/root/cimv2").ExecQuery("Select * from Win32_UserAccount WHERE Domain = '" & strComputer & "'")
FOR EACH objUser IN objSystem
 IF Left(objUser.SID, 8) = "S-1-5-21" AND Right(objUser.SID, 3) = "500" THEN
  SET oSystem = GetObject("WinNT://" & strComputer)
  SET oUser = oSystem.GetObject("user", objUser.Name)
  oUser.SetPassword "NEW_PASSWORD"
  oUser.SetInfo
 END IF
NEXT

Скрипт успешно тестировался на всех версиях ОС Windows начиная с XP.