Что нового

_WinUser UDF v2.6 - работа с учетными записями и группами Windows

Автор
sss

sss

Продвинутый
Сообщения
332
Репутация
96
Прошу прощения. Я тут постоянно меняю географическое местоположение, да еще приболел немного, совсем забыл про Вас.

Судя по всему, мусор в консоль валится по потоку STDERR, который я как раз не перехватывал. В вашем случае выбрасывается ошибка "Не найдено имя пользователя", что довольно странно - у меня так же неактивен гость, но STDERR пуст.

Библиотеку в шапке пока обновлять не буду (надо маленько подшлифовать, как силы появятся), пока сброшу сюда
Код:
#include <Constants.au3>

Global $__WinUser_RunAs_name = Default
Global $__WinUser_RunAs_pass = ""
Global $__WinUser_RunAs_domain = @ComputerName

;
;		WinUser UDF
;				version 2.7.0b
;
;	Библиотека для работы (добавление, удаление, установка параметров) с пользователями (учетными записями) Windows.
;   Делал для себя, решил выложить, может, пригодится. Использует net user и net localgroup.
;   Все функции работают в русской и английской версиях WinXP и Win7.
;   Большое спасибо Yuriy @ autoit-script.ru - благодаря его посту я узнал о этом методе
;	 А также спасибо VladUs @ autoit-script.ru за функцию _WinUser_GetSID
;
;	Обновления и обсуждения можно найти тут: http://autoit-script.ru/index.php/topic,4667.0.html
;
;	Дата обновления - 02.09.2015
;

; Список функций: ( * - новая функция, которой не было в прошлом релизе)
;   _WinUser_Add
;   _WinUser_AddToGroup
;   _WinUser_CreateGroup
;   _WinUser_Delete
;   _WinUser_DeleteFromGroup
;   _WinUser_DeleteGroup
; * _WinUser_ExecAs
;   _WinUser_GetAll
;   _WinUser_GetAllNames
;   _WinUser_GetComment
;   _WinUser_GetCountryCode
;   _WinUser_GetCountryName
;   _WinUser_GetFullName
;   _WinUser_GetLastLoginTime
;   _WinUser_GetSID
;   _WinUser_IsActive
;   _WinUser_IsAdmin
;   _WinUser_SetAll
;   _WinUser_SetActive
;   _WinUser_SetAdmin
;   _WinUser_SetComment
;   _WinUser_SetCountryCode
;   _WinUser_SetFullName
;   _WinUser_SetLoginScript
;   _WinUser_SetPassword


; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_Add
; Описание.......:	Создает учетную запись пользователя
; Синтаксис......:	_WinUser_Add($name, [$pass='', [$admin=0, [$active=1, [$full_name=$name, [$comment='', [$may_change_pass=1 ]]]]]])
;
; Параметры.....:	$name  - Имя учетной записи.
;                   $pass - [Опционально] Пароль.
;                   $admin - [Опционально] 1 - Админ, 0 - юзер.
;                   $active - [Опционально] 1 - Активен, 0 - неактивен.
;                   $full_name - [Опционально] Полное имя уч. записи.
;                   $comment  - [Опционально] Комментарий.
;                   $may_change_pass - [Опционально] 1 - Может изменить пароль, 0 - не может
; Возврат.......:	Успех               - Возвращает 1 и устанавливает @error=0.
;					Неудача             - Устанавливает @error=1 и возвращает:
;                                           2 - Неправильный пароль (слишком длинный)
;                                           3 - Неправильные параметры
;                                           4 - Не могу создать уч. запись
;                                           5 - Не могу изменить группу пользователя (Админские или пользовательские права)
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_Add($name, $pass = '', $admin = 0, $active = 1, $full_name = $name, $comment = '', $may_change_pass = 1)
	If StringLen($pass) > 14 Then
		SetError(1)
		Return 2
	EndIf
	If $admin - 1 > 1 Or $active - 1 > 1 Or $may_change_pass - 1 > 1 Then
		SetError(1)
		Return 3
	EndIf
	$localgroup_string = 'net localgroup '
	If $admin = 1 Then
		$localgroup_string &= __WinUser_GetString('admin-group' & ' "' & $name & '" /add')
	EndIf
	If $active = 1 Then
		$active = 'YES'
	Else
		$active = 'NO'
	EndIf
	$user_string = 'net user "' & $name & '" "' & $pass & '" /ACTIVE:' & $active & ' /COMMENT:"' & $comment & '" /FULLNAME:"' & $full_name & '"'
	If $may_change_pass = 1 Then
		$user_string &= ' /PASSWORDCHG:YES /add'
	Else
		$user_string &= ' /PASSWORDCHG:NO /add'
	EndIf
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 4
	EndIf

	If $localgroup_string <> 'net localgroup ' Then
		$data = __WinUser_Run($localgroup_string)
		If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
			SetError(1)
			_WinUser_Delete($name)
			Return 5
		EndIf
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_Add

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_Delete
; Описание.......:	Удаляет учетную запись пользователя
; Синтаксис......:	_WinUser_Delete($name)
;
; Параметры......:	$name  - Имя учетной записи.
; Возврат........:	Успех                 - Возвращает 1 и устанавливает @error=0.
;					Неудача               - Возвращает 0 и устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_Delete($name)
	$data = __WinUser_Run('net user "' & $name & '" /delete')
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_Delete

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetPassword
; Описание.......:	Устанавливает пароль на учетную запись
; Синтаксис......:	_WinUser_SetPassword($name, [$new_pass])
;
; Параметры......:	$name  - Имя учетной записи.
;                   $new_pass - Новый парол (если не указано или пустой - без пароля)
; Возврат........:	Успех                 - Возвращает 1 и устанавливает @error=0.
;					Неудача               - Возвращает 0 и устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetPassword($name, $new_pass = '')
	$user_string = 'net user "' & $name
	If $new_pass = '' Then
		$user_string &= '" /PASSWORDREQ:NO'
	Else
		$user_string &= '" "' & $new_pass & '" /PASSWORDREQ:YES'
	EndIf
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_SetPassword

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetAdmin
; Описание.......:	Ставит или убирает Админские права учетной записи
; Синтаксис......:	_WinUser_SetAdmin($name, [$admin])
;
; Параметры......:	$name  - Имя учетной записи.
;                   $admin - 1 - Админ, 0 - Пользователь (по умочанию - 1)
; Возврат........:	Успех                 - Возвращает 1 и устанавливает @error=0.
;					Неудача               - Возвращает 0 и устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetAdmin($name, $admin = 1)
	$localgroup_string = 'net localgroup "' & __WinUser_GetString('admin-group') & '" "' & $name
	If $admin = 1 Then
		$localgroup_string &= '" /add'
	ElseIf $admin = 0 Then
		$localgroup_string &= '" /delete'
	EndIf
	$data = __WinUser_Run($localgroup_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_SetAdmin

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetActive
; Описание.......:	Активирует\деактивирует учетную запись пользователя
; Синтаксис......:	_WinUser_SetActive($name, [$active])
;
; Параметры......:	$name  - Имя учетной записи.
;                   $active - 1 - активировать, 0 - деактивировать (по умолчанию - 1)
; Возврат........:	Успех                 - Возвращает 1 и устанавливает @error=0.
;					Неудача               - Возвращает 0 и устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetActive($name, $active = 1)
	$user_string = 'net user "' & $name & '" /ACTIVE:'
	If $active = 1 Then
		$user_string &= 'YES'
	ElseIf $active = 0 Then
		$user_string &= 'NO'
	EndIf
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_SetActive

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_IsActive
; Описание.......:	Проверяет активность учетной записи
; Синтаксис......:	_WinUser_IsActive($name)
;
; Параметры......:	$name  - Имя учетной записи.
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает: 1 если активна, 0 если неактивна.
;					Неудача               - Возвращает 0 и устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_IsActive($name)
	Dim $string = ''
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	$data_split = StringSplit($data, @CRLF)
	For $i = 1 To UBound($data_split) - 1 Step 1
		If StringInStr($data_split[$i], __WinUser_GetString('active')) Then
			$string = $data_split[$i]
			ExitLoop
		EndIf
	Next
	If $string = '' Then
		SetError(1)
		Return 0
	EndIf
	$string = StringStripWS(StringReplace($string, __WinUser_GetString('active'), ''), 1)
	Switch $string
		Case 'Yes'
			SetError(0)
			Return 1
		Case 'No'
			SetError(0)
			Return 0
	EndSwitch
EndFunc   ;==>_WinUser_IsActive

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_IsAdmin
; Описание.......:	Проверяет, если Админские права у учетной записи
; Синтаксис......:	_WinUser_IsAdmin($name)
;
; Параметры......:	$name  - Имя учетной записи.
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает: 1 если админ, 0 если пользователь.
;					Неудача               - устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_IsAdmin($name)
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	$data_split = StringSplit($data, @CRLF)
	$z = 0
	For $i = 1 To UBound($data_split) - 1 Step 1
		If StringInStr($data_split[$i], __WinUser_GetString('is-admin')) > 0 Then
			$z = $i
			ExitLoop
		EndIf
	Next
	If $z = 0 Then
		SetError(1)
		Return 2
	EndIf
	$string = $data_split[$z]
	If StringInStr($string, __WinUser_GetString('admin-group')) > 0 Then
		SetError(0)
		Return 1
	Else
		SetError(0)
		Return 0
	EndIf
EndFunc   ;==>_WinUser_IsAdmin

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetFullName
; Описание.......:	Djвращает полное имя учетной записи
; Синтаксис......:	_WinUser_GetFullName($name)
;
; Параметры......:	$name  - Имя учетной записи.
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает полное имя.
;					Неудача               - устанавливает @error=1 и возвращает 0.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetFullName($name)
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	$full_name = StringRegExp($data, __WinUser_GetString('full_name') & ' *(.*)', 3)
	$full_name = $full_name[0]
	Return StringStripCR($full_name)
EndFunc   ;==>_WinUser_GetFullName

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetComment
; Описание.......:	Возвращает комментарий учетной записи
; Синтаксис......:	_WinUser_GetComment($name)
;
; Параметры......:	$name  - Имя учетной записи.
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает комментарий (если комментария нет - NO COMMENT).
;					Неудача               - устанавливает @error=1 и возвращает 0.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetComment($name)
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	$comment = StringRegExp($data, __WinUser_GetString('comment') & ' *(.*)', 3)
	$comment = $comment[0]
	If $comment = 'NO_COMMENT' Then $comment = ''
	Return StringStripCR($comment)
EndFunc   ;==>_WinUser_GetComment

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetLastLoginTime
; Описание.......:	Возвращает дату последнего входа
; Синтаксис......:	_WinUser_GetLastLoginTime($name)
;
; Параметры......:	$name  - Имя учетной записи.
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает дату в формате дд.мм.гг чч.мм
;					Неудача               - устанавливает @error=1 и возвращает 0.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetLastLoginTime($name)
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	$data_split = StringSplit($data, @CRLF)
	$z = 0
	For $i = 1 To UBound($data_split) - 1 Step 1
		If StringInStr($data_split[$i], __WinUser_GetString('last-login')) > 0 Then
			$z = $i
			ExitLoop
		EndIf
	Next
	If $z = 0 Then
		SetError(1)
		Return 2
	EndIf
	$string = $data_split[$z]
	$string = StringReplace($string, __WinUser_GetString('last-login'), '')
	$string = StringStripWS($string, 1)
	$string = StringReplace($string, '/', '.')
	$string_splitt = StringSplit($string, ' ')
	$string_splitt2 = StringSplit($string_splitt[1], '.')
	$month = $string_splitt2[1]
	$day = $string_splitt2[2]
	$year = $string_splitt2[3]
	$temp = StringInStr($string, 'AM')
	If $temp > 0 Then
		$string = StringTrimRight($string, 2)
		$string_splitt3 = StringSplit($string, ' ')
		$string = $day & '.' & $month & '.' & $year & ' ' & $string_splitt3[2]
	EndIf
	$temp2 = StringInStr($string, 'PM')
	If $temp2 > 0 Then
		$string = StringTrimRight($string, StringLen($string) - $temp2 - 1)
		$temp3 = StringSplit($string, ' ')
		$time = $temp3[2]
		$temp4 = StringSplit($time, ':')
		$string = $day & '.' & $month & '.' & $year & ' ' & $temp4[1] + 12 & ':' & $temp4[2]
	EndIf
	SetError(0)
	Return $string
EndFunc   ;==>_WinUser_GetLastLoginTime

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetComment
; Описание.......:	Устанавливает комментарий для учетной записи
; Синтаксис......:	_WinUser_SetComment($name, [$comment=''])
;
; Параметры......:	$name     - Имя учетной записи.
;                   $comment  - комментарий (если не указан - без комментария)
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает 1.
;					Неудача               - устанавливает @error=1 и возвращает 0.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetComment($name, $comment = '')
	$user_string = 'net user "' & $name & '" /COMMENT:"' & $comment & '"'
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_SetComment

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetSID
; Описание.......:	Возвращает SID учетной записи
; Синтаксис......:	_WinUser_GetSID($strName)
;
; Параметры......:	$strName     - Имя учетной записи.
; Возврат........:	Успех                 - возвращает SID.
;					Неудача               - возвращает 0.
; Автор..........:	VladUs, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetSID($strName)
	$strComputer = "."
	$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
	$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_UserAccount WHERE Name =" & "'" & $strName & "'")
	For $objItem In $colItems
		$name = $objItem.Name
		$SID = $objItem.SID
		Return $SID
	Next
EndFunc   ;==>_WinUser_GetSID

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetAllNames
; Описание.......:	Возвращает массив всех учетных записей
; Синтаксис......:	_WinUser_GetAllNames()
;
; Параметры......:	нет
; Возврат........:	Успех                 - возвращает массив:
;                                               [0] - кол-во учетных записей
;                                               [n] - имя учетной записи n
;					Неудача               - возвращает 0 и устанавливает @error=1.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetAllNames()
	$data = __WinUser_Run("net user")
	If StringInStr($data, __WinUser_GetString('success')) = 0 Then
		SetError(1)
		Return 0
	EndIf
	$data = StringRegExp($data, '(?s)-{79}(.*?)' & __WinUser_GetString('success'), 3)
	$data = StringRegExp(StringTrimLeft(StringReplace($data[0] & '  ', @CRLF, '  '), 2), '(.*?) {1,30}| {1,30}(.*?)', 3)
	Dim $ret[UBound($data) + 1]
	$ret[0] = UBound($data)
	For $i = 1 To UBound($data)
		$ret[$i] = $data[$i - 1]
	Next
	Return $ret
EndFunc   ;==>_WinUser_GetAllNames

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetCountryCode
; Описание.......:	Устанавливает код страны для учетной записи
; Синтаксис......:	_WinUser_SetCountryCode($name, [$code=0])
;
; Параметры......:	$name - имя учетной записи
;                   $code - код страны (если не указан = 0, страна по умолчанию)
; Возврат........:	Успех                 - возвращает 1
;					Неудача               - возвращает 0 и устанавливает @error=1.
; Пометки........;  Коды стран можно найти здесь: http://whoyougle.ru/place/countries/list/ в колонке "Телефонный код"
;                   Писать без плюса!
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetCountryCode($name, $code)
	$user_string = 'net user "' & $name & '" /COUNTRYCODE:' & $code
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_SetCountryCode

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetCountryCode
; Описание.......:	Возвращает код страны учетной записи
; Синтаксис......:	_WinUser_GetCountryCode($name)
;
; Параметры......:	$name - имя учетной записи
; Возврат........:	Успех                 - возвращает код страны
;					Неудача               - возвращает -1 и устанавливает @error=1.
; Пометки........;  Коды стран можно найти здесь: http://whoyougle.ru/place/countries/list/ в колонке "Телефонный код"
;                   Писать без плюса!
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetCountryCode($name)
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	$split = StringSplit($data, @CRLF)
	$z = 0
	For $i = 1 To UBound($split) - 1 Step 1
		If StringInStr($split[$i], __WinUser_GetString('country-code')) = 1 Then
			$z = $i
			ExitLoop
		EndIf
	Next
	If $z = 0 Then
		SetError(1)
		Return -2
	EndIf
	$string = $split[$z]
	$string = StringReplace(StringStripWS($string, 4), __WinUser_GetString('country-code'), '')
	$split2 = StringSplit($string, '')
	$data = ''
	For $i = 1 To UBound($split2) - 1 Step 1
		If $split2[$i] = '(' Then ExitLoop
		$data = $data & $split2[$i]
	Next
	Return StringStripWS($data, 8)
EndFunc   ;==>_WinUser_GetCountryCode

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetCountryName
; Описание.......:	Возвращает имя страны учетной записи
; Синтаксис......:	_WinUser_GetCountryName($name)
;
; Параметры......:	$name - имя учетной записи
; Возврат........:	Успех                 - возвращает имя страны
;					Неудача               - возвращает -1 и устанавливает @error=1.
; Пометки........;  Коды стран можно найти здесь: http://whoyougle.ru/place/countries/list/ в колонке "Телефонный код"
;                   Писать без плюса!
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetCountryName($name)
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	$split = StringSplit($data, @CRLF)
	$z = 0
	For $i = 1 To UBound($split) - 1 Step 1
		If StringInStr($split[$i], __WinUser_GetString('country-code')) = 1 Then
			$z = $i
			ExitLoop
		EndIf
	Next
	If $z = 0 Then
		SetError(1)
		Return -2
	EndIf
	$string = $split[$z]
	$split = StringSplit($string, '(')
	$split2 = StringSplit($split[2], ')')
	Return $split2[1]
EndFunc   ;==>_WinUser_GetCountryName

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetLoginScript
; Описание.......:	Устанавливает скрипт сценария входа для учетной записи
; Синтаксис......:	_WinUser_SetLoginScript($name, [$path=''])
;
; Параметры......:	$name     - Имя учетной записи.
;                   $path     - путь до сценария входа
; Возврат........:	Успех                 - устанавливает @error=0 и возвращает 1.
;					Неудача               - устанавливает @error=1 и возвращает 0.
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetLoginScript($name, $path = '')
	$user_string = 'net user "' & $name & '" /SCRIPTPATH:"' & $path & '"'
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	Else
		SetError(0)
		Return 1
	EndIf
EndFunc   ;==>_WinUser_SetLoginScript

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_SetAll
; Описание.......:	Настраивает учетную запись пользователя
; Синтаксис......:	_WinUser_SetAll($name, [$pass='', [$admin=0, [$active=1, [$full_name='', [$comment='', [$may_change_pass=1 ]]]]]])
;
; Параметры.....:	$name  - Имя учетной записи.
;                   $pass - [Опционально] Пароль.
;                   $admin - [Опционально] 1 - Админ, 0 - юзер.
;                   $active - [Опционально] 1 - Активен, 0 - неактивен.
;                   $full_name - [Опционально] Полное имя уч. записи.
;                   $comment  - [Опционально] Комментарий.
;                   $may_change_pass - [Опционально] 1 - Может изменить пароль, 0 - не может
; Возврат.......:	Успех               - Возвращает 1 и устанавливает @error=0.
;					Неудача             - Устанавливает @error=1 и возвращает:
;                                           2 - Неправильный пароль (слишком длинный)
;                                           3 - Неправильные параметры
;                                           4 - Не могу изменить свойства уч. запись
;                                           5 - Не могу изменить группу пользователя (Админские или пользовательские права)
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_SetAll($name, $pass = '', $admin = 0, $active = 1, $full_name = '', $comment = '', $may_change_pass = 1)
	If StringLen($pass) > 14 Then
		SetError(1)
		Return 2
	EndIf
	If $admin > 1 Or $admin < 0 Or $active > 1 Or $active < 0 Or $may_change_pass > 1 Or $may_change_pass < 0 Then
		SetError(1)
		Return 3
	EndIf
	$localgroup_string = 'net localgroup ' & __WinUser_GetString('admin-group') & ' "' & $name
	If $admin = 1 Then
		$localgroup_string &= '" /add'
	Else
		$localgroup_string &= '" /delete'
	EndIf
	If $active = 1 Then
		$active = 'YES'
	Else
		$active = 'NO'
	EndIf
	$user_string = 'net user "' & $name & '" "' & $pass & '" /ACTIVE:' & $active & ' /COMMENT:"' & $comment & '" /FULLNAME:"' & $full_name & '"'
	If $may_change_pass = 1 Then
		$user_string &= ' /PASSWORDCHG:YES'
	Else
		$user_string &= ' /PASSWORDCHG:NO'
	EndIf
	$data = __WinUser_Run($user_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 4
	EndIf
	$data = __WinUser_Run($localgroup_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 5
	EndIf
	SetError(0)
	Return 1
EndFunc   ;==>_WinUser_SetAll


; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_GetAll
; Описание.......:	Возвращает все данные о учетной записи пользователя
; Синтаксис......:	_WinUser_GetAll($name)
;
; Параметры.....:	$name  - Имя учетной записи.
; Возврат.......:	Успех               - Возвращает одномерный массив и устанавливает @error=0.
;                                         [0] - Полное имя
;                                         [1] - Комментарий
;                                         [2] - Если админ, то 1 (иначе 0)
;                                         [3] - Если активен, то 1 (иначе 0)
;                                         [4] - Код страны
;                                         [5] - Страна
;					Неудача             - Устанавливает @error=1 и возвращает 0
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_GetAll($name)
	MsgBox(0, '', '1')
	$user_string = 'net user "' & $name & '"'
	$data = __WinUser_Run($user_string)
	MsgBox(0, '', '2')
	$full_name = StringRegExp($data, __WinUser_GetString('name') & ' *(.*)', 3)
	$full_name = $full_name[0]

	$comment = StringRegExp($data, __WinUser_GetString('comment') & ' *(.*)', 3)
	$comment = $comment[0]
	If $comment = 'NO_COMMENT' Then $comment = ''
	MsgBox(0, '', '3')

;~ 	$country = StringRegExp($data, __WinUser_GetString('country-code') & ' *(\d*) \((.*)\)', 3)
;~ 	$country_code = $country[0]
;~ 	$country_name = $country[1]

	MsgBox(0, '', '4')

	$active = StringRegExp($data, __WinUser_GetString('active') & ' *(.*)', 3)
	$active = $active[0]
	If $active = 'Yes' Then
		$active = 1
		MsgBox(0, '', '5')
	Else
		$active = 0
		MsgBox(0, '', '6')
	EndIf

	If StringInStr($data, __WinUser_GetString('admin-group')) Then
		$admin = 1
		MsgBox(0, '', '7')
	Else
		$admin = 0
		MsgBox(0, '', '8')
	EndIf

	Dim $return[6]
	$return[0] = StringStripCR($full_name)
	$return[1] = StringStripCR($comment)
	$return[2] = $admin
	$return[3] = $active
;~ 	$return[4] = $country_code
;~ 	$return[5] = $country_name
	Return $return
EndFunc   ;==>_WinUser_GetAll

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_AddToGroup
; Описание.......:	Добавляет пользователя в группу
; Синтаксис......:	_WinUser_AddToGroup($name, $group)
;
; Параметры.....:	$name  - Имя учетной записи.
;                   $group - Группа
;
; Возврат.......:	Успех               - Возвращает 1 и устанавливает @error=0.
;					Неудача             - Устанавливает @error=1 и возвращает 0
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_AddToGroup($name, $group)
	$localgroup_string = 'net localgroup "' & $group & '" "' & $name & '" /add'
	$data = __WinUser_Run($localgroup_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	Else
		SetError(0)
		Return 1
	EndIf
EndFunc   ;==>_WinUser_AddToGroup

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_DeleteFromGroup
; Описание.......:	Удаляет пользователя из группы
; Синтаксис......:	_WinUser_DeleteFromGroup($name, $group)
;
; Параметры.....:	$name  - Имя учетной записи.
;                   $group - Группа
;
; Возврат.......:	Успех               - Возвращает 1 и устанавливает @error=0.
;					Неудача             - Устанавливает @error=1 и возвращает 0
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_RemoveFromGroup($name, $group)
	$localgroup_string = 'net localgroup "' & $group & '" "' & $name & '" /delete'
	$data = __WinUser_Run($localgroup_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	Else
		SetError(0)
		Return 1
	EndIf
EndFunc   ;==>_WinUser_RemoveFromGroup

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_CreateGroup
; Описание.......:	Создает группу
; Синтаксис......:	_WinUser_CreateGroup($group)
;
; Параметры.....:	$group - Группа
;
; Возврат.......:	Успех               - Возвращает 1 и устанавливает @error=0.
;					Неудача             - Устанавливает @error=1 и возвращает 0
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_CreateGroup($group)
	$localgroup_string = 'net localgroup "' & $group & '" /add'
	$data = __WinUser_Run($localgroup_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	Else
		SetError(0)
		Return 1
	EndIf
EndFunc   ;==>_WinUser_CreateGroup

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_DeleteGroup
; Описание.......:	Удаляет группу
; Синтаксис......:	_WinUser_DeleteGroup($group)
;
; Параметры.....:	$group - Группа
;
; Возврат.......:	Успех               - Возвращает 1 и устанавливает @error=0.
;					Неудача             - Устанавливает @error=1 и возвращает 0
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_DeleteGroup($group)
	$localgroup_string = 'net localgroup "' & $group & '" /delete'
	$data = __WinUser_Run($localgroup_string)
	If Not StringInStr($data, __WinUser_GetString('success')) = 1 Then
		SetError(1)
		Return 0
	Else
		SetError(0)
		Return 1
	EndIf
EndFunc   ;==>_WinUser_DeleteGroup

; #ФУНКЦИЯ# ====================================================================================================
; Имя............:	_WinUser_ExecAs
; Описание.......:	Устанавливает, от чьей учетной записи будут выполняться команды _WinUser...
;					 Если не указывать аргументы или указать имя Default, команды будут выполняться
;					 от текущего пользователя
; Синтаксис......:	_WinUser_ExecAs($name, $pass, $domain)
;
; Параметры.....:	$name - Имя учетной записи
;					$pass - Пароль учетной записи
;					$domain - Домен
;
; Возврат.......:	Нет
; Автор..........:	Sky-WaLkeR, www.autoit-script.ru
; ===============================================================================================================
Func _WinUser_ExecAs($name = Default, $pass = "", $domain = Default)
	If $domain = Default Then $domain = __WinUser_GetDomain()
	$__WinUser_RunAs_domain = $domain
	$__WinUser_RunAs_name = $name
	$__WinUser_RunAs_pass = $pass
EndFunc   ;==>_WinUser_ExecAs

Func __WinUser_Run($cmd, $runas_name = $__WinUser_RunAs_name, $runas_pass = $__WinUser_RunAs_pass, $runas_domain = $__WinUser_RunAs_domain)
	If $__WinUser_RunAs_name = Default Then
		$proc = Run('cmd.exe', '', 0, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
	Else
		$proc = RunAs($runas_name, $runas_domain, $runas_pass, $RUN_LOGON_NOPROFILE, 'cmd.exe', '', 0, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
	EndIf
	StdinWrite($proc, _Encoding_1251To866($cmd) & @CRLF)
	StdinWrite($proc)
	$data = ''
	$stderr = ''
	While True
		$data &= StdoutRead($proc)
		$stderr &= StderrRead($proc)
		If @error Then ExitLoop
		Sleep(25)
	WEnd
	If $stderr <> '' Then
		SetError(1)
;~ 		ConsoleWrite(_Encoding_866To1251($stderr))
		Return 0
	EndIf
	SetError(0)
	Return _Encoding_866To1251($data)
EndFunc   ;==>__WinUser_Run

Func __WinUser_GetDomain()
	;$data = __WinUser_Run("ipconfig /all")
	;$domain = StringRegExp($data, __WinUser_GetString("domain") & ".*?:(.*)", 3)
	;$domain = $domain[0]
	;If $domain = "" Then $domain = @ComputerName
	;Return $domain
    Return @ComputerName
EndFunc   ;==>__WinUser_GetDomain


Func __WinUser_GetString($flag)
	Switch $flag
		Case 'success'
			If @OSLang = 0419 Then
				Return 'Команда выполнена успешно'
			Else
				Return 'The command completed successfully'
			EndIf
		Case 'name'
			If @OSLang = 0419 Then
				Return 'Полное имя'
			Else
				Return 'Full Name'
			EndIf
		Case 'comment'
			If @OSLang = 0419 Then
				Return 'Комментарий'
			Else
				Return 'Comment'
			EndIf
		Case 'country-code'
			If @OSLang = 0419 Then
				Return 'Код страны'
			Else
				Return 'Country code'
			EndIf
		Case 'active'
			If @OSLang = 0419 Then
				Return 'Учетная запись активна'
			Else
				Return 'Account active'
			EndIf
		Case 'pass-required'
			If @OSLang = 0419 Then
				Return 'Требуется пароль'
			Else
				Return 'Password required'
			EndIf
		Case 'may-change-pass'
			If @OSLang = 0419 Then
				Return 'Пользователь может изменить пароль'
			Else
				Return 'User may change password'
			EndIf
		Case 'logon-script'
			If @OSLang = 0419 Then
				Return 'Сценарий входа'
			Else
				Return 'Logon script'
			EndIf
		Case 'last-login'
			If @OSLang = 0419 Then
				Return 'Последний вход'
			Else
				Return 'Last logon'
			EndIf
		Case 'is-admin'
			If @OSLang = 0419 Then
				Return 'Членство в локальных группах'
			Else
				Return 'Local Group Memberships'
			EndIf
		Case 'admin-group'
			If @OSLang = 0419 Then
				Return 'Администраторы'
			Else
				Return 'Administrators'
			EndIf
		Case 'user-group'
			If @OSLang = 0419 Then
				Return 'Пользователи'
			Else
				Return 'Users'
			EndIf
		Case 'domain'
			If @OSLang = 0419 Then
				Return 'Основной DNS-суффикс'
			Else
				Return 'Primary Dns Suffix'
			EndIf
	EndSwitch
EndFunc   ;==>__WinUser_GetString

Func _Encoding_866To1251($sString)
	Local $sResult = "", $iCode
	Local $Var866Arr = StringSplit($sString, "")

	For $i = 1 To $Var866Arr[0]
		$iCode = Asc($Var866Arr[$i])

		Select
			Case $iCode >= 128 And $iCode <= 175
				$Var866Arr[$i] = Chr($iCode + 64)
			Case $iCode >= 224 And $iCode <= 239
				$Var866Arr[$i] = Chr($iCode + 16)
			Case $iCode = 240
				$Var866Arr[$i] = Chr(168)
			Case $iCode = 241
				$Var866Arr[$i] = Chr(184)
			Case $iCode = 252
				$Var866Arr[$i] = Chr(185)
		EndSelect

		$sResult &= $Var866Arr[$i]
	Next

	Return $sResult
EndFunc   ;==>_Encoding_866To1251

Func _Encoding_1251To866($sString)
	Local $sResult = "", $iCode
	Local $Var1251Arr = StringSplit($sString, "")

	For $i = 1 To $Var1251Arr[0]
		$iCode = Asc($Var1251Arr[$i])

		Select
			Case $iCode >= 192 And $iCode <= 239
				$Var1251Arr[$i] = Chr($iCode - 64)
			Case $iCode >= 240 And $iCode <= 255
				$Var1251Arr[$i] = Chr($iCode - 16)
			Case $iCode = 168
				$Var1251Arr[$i] = Chr(240)
			Case $iCode = 184
				$Var1251Arr[$i] = Chr(241)
			Case $iCode = 185
				$Var1251Arr[$i] = Chr(252)
		EndSelect

		$sResult &= $Var1251Arr[$i]
	Next

	Return $sResult
EndFunc   ;==>_Encoding_1251To866

Новая функция, _WinUser_ExecAs, позволяет указать, от чьего имени делать команды. Если вызвать без параметров (или вообще не вызывать), будет использоваться обычный Run вместо RunAs. Примерчик:
Код:
#RequireAdmin

_WinUser_IsAdmin("Гость") ; вызов под текущим пользователем
_WinUser_ExecAs("Admin", "password") ; переключаем на вызовы под админом
_WinUser_IsAdmin("Гость") ; вызов под админом

Тонкие моменты:
• Пока не добавил в начало примера #RequireAdmin, не работало даже с вызовом под своей учетной записью. Видимо, из-за UAC или еще чего.
• Из функции _WinUser_GetAll убрано получение информации о стране. На Windows 10 не заработало, видимо, изменилось что-то. Можно вернуть, раскоментировав строки 684-685. Отдельные функции по странам оставил, но на Win10 скорее всего поломается.
• Чтобы перенаправить вывод STDERR обратно в консоль (только теперь не кракозябрами на cp866, а уже нормальным текстом), раскомментировать строку 822
• Обработка ошибки через STDERR пока не сделана, хотя __WinUser_Run уже умеет возвращать ее. Доделаю, когда буду в нормальном самочувствии.

(поэтому в шапку и не бросаю пока...)

Если найдете еще что-то, с удовольствием выслушаю и постараюсь пофиксить \ реализовать.
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Спасибо


Добавлено:
Сообщение автоматически объединено:

Правильно ли я понял, что данная реализация не подойдет к доменной структуре?
В качестве домена подставляется @ComputerName

В _WinUser_ExecAs() можно добавить третий параметр, который по умолчанию будет принимать значение @ComputerName
Кстати, домен текущего соединения так же можно получить, используя Ваш скрипт, немного доработав
ipconfig /all
"Основной DNS-суффикс"
Но это если я не ошибаюсь.


Добавлено:
Сообщение автоматически объединено:

Что то вроде такого:

Код:
$user_string = 'ipconfig /all'
$data = __WinUser_Run($user_string)
$domen = StringRegExp($data, 'Основной DNS-суффикс' & '.*: (.*)', 3)
$domen = $domen[0]
ConsoleWrite($domen & @CRLF)



Добавлено:
Сообщение автоматически объединено:

Хотя нет. Это скорее всего частный случай, который работает только у меня.


Добавлено:
Сообщение автоматически объединено:

Вы используете переменную $RUN_LOGON_NOPROFILE.
При этом я не нашел, где присваивается значение.
 
Автор
sss

sss

Продвинутый
Сообщения
332
Репутация
96
Обновил предыдущий пост - добавил третий параметр (домен) в функцию __WinUser_ExecAs.

Насчет авто-поиска доменного имени ничего сказать не могу, под доменом (по крайней мере AD) не сидел. Вполне возможно, что Ваш вариант сработает в 99% случаях, но только нужен еще этот текст с английской системы, и немного дополнить код, чтобы у людей вне домена тоже работало.

Код:
$data = __WinUser_Run("ipconfig /all")
; $domain = StringRegExp($data, __WinUser_GetString("domain")&".*?:(.*)", 3)
$domain = StringRegExp($data, 'Основной DNS-суффикс.*?: (.*)', 3)
$domain = $domain[0]
If $domain = "" Then $domain = @ComputerName


Я правильно понимаю - в аргумент domain функции RunAs нужно подставить нечто в виде %домен%\\%имя_компьютера%, или просто домен (результат, полученный выше)?

Переменная объявлена в Constants.au3, который подключен в WinUser.au3

UPD: вопрос с английской системой снят ("Primary Dns Suffix"), остался только вопрос выше.
UPD2: слушайте, а в выводе команды "net user" случаем не присутствует искомое? http://prntscr.com/8c5mdx
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
1. В выводе команды "net user" у меня отображается мое сетевое имя.
2. С английским все верно. В RunAs нужно подставить %домен%. Без имени ПК.

Думаю, с поиском доменом дорабатывать все же не стоит. Походу, там все сложнее. У меня частный случай.
Найденное значение действительно является суффиксом DNS, и у нас оно совпадает с доменом.
Но это целиком и полностью настраивается, и не обязательно суффикс ДНС совпадет с именем домена.

Так что тут нужно искать способ получения ДНС. Поинтересуюсь у знакомых.

Как найду, напишу.
 
Верх