PowerShell. Автопроверка состава групп доступа

Задача:
1) Пройтись по всем группам, имеющим префикс «FS_»
2) Проверить их состав
Если нашел группу с префиксом «Штатка_» — проверяем следующего члена группы
Если найдет пользователя:
— смотрим есть ли у него группа с префиксом «Штатка_»
— если есть — добавляем ее в родительскую группу с префиксом «FS_»
— удаляем пользователя
3) Переходим к следующей группе с префиксом «FS_»

Решение:
Под данную задачу был написан скрипт, выполняющий следующие действия:

1) выгружаем все группы FS_* из определенной OU, идем в цикл по группам
2) выгружаем всех пользователей данной группы FS_*, !группы не выгружаем!
3) цикл по пользователю:
a) Находим его группу Штатка_*
b) Выкидываем пользака из группы FS_*
c) На группу FS_* вешаем группу Штатка_* пользователя
d) Пишем все прелюбодеяния в лог
4) Переходим к следующей группе FS_*
Сам скрипт:
cls
#Блок с функцией логирования в файл и вывода инфы в консоль
################################################################################
Function Write-HostAndLog { 
param ($FuncWHLText,$FuncWHLOutFile) 
Write-Host $FuncWHLText 
Add-Content $FuncWHLOutFile $FuncWHLText 
}
################################################################################
#Конец блока с функцией логирования

#Основной блок
#Обнуляем переменные
$alien_group = $null 
$al_group = $null 
$alien_group_name = $null 
$users = $null 
$group = $null 
$groups_fs = $null 
$gpname = $null 
$group = $null 
$group_name = $null 
$group_name_new_full = $null 
$group_sid = $null 
$groups_fs = $null 
$user = $null 
$user_name = $null 
$user_group = $null 

#Ищем группы по маске FS_* в нужной OU
$groups_fs = Get-ADGroup -Filter 'Name -like "FS_*"' -SearchBase "OU=Groups,DC=corporate,DC=local" | Sort-Object Name #| FT Name,SID -A 

#Конвеер по группам
$groups_fs | %{ 
$group = $_ 
$group_name = $group.name 
$group_sid = $group.SID 
$group_name_new_full = "C:\logs\FS\"+$group_name+".log" #Формируем имя лог-файла 
Write-Host "Проверяю группу < <"$group_name">>" 

#Начинаем КВН 
$alien_group = Get-ADGroupMember $group_sid | where {$_.objectclass -match “group” -and $_.name -cnotlike "Штатка_*"} | select name #Ищем группу, имеющую название отличное от Штатка_* 
	if ($alien_group -ne "") 
		{
		$alien_group | %{ 
		$al_group = $_ 
		$alien_group_name = $al_group.name 
		Write-HostAndLog "Нашел левую группу < <$alien_group_name>> в группе < <$group_name>>!" "c:\logs\FS\_alien.log" #репортим в лог и консоль об этой проблеме
		}
	}
#Заканчиваем КВН 

$users = Get-ADGroupMember $group_sid | where {$_.objectclass -match “user”} #Выгружаем всех пользователей группы, группы внутри группы не трогаем 
	if ($users -eq $null) 
		{
		Write-HostAndLog "Группа < <$group_name>> девственно пуста " "c:\logs\FS\_all_right.log" #Проверяем найдены ли УЗ в группе, если нет - пишем в файл 
		}
	else #Если УЗ в группе найдены - идем дальше 
		{
		$users | %{ 
		$user = $_ 
		$user_name = $user.SamAccountName 
		$user_group = Get-ADPrincipalGroupMembership $user | where {$_.name -like "Штатка_*"} | select name #Ищем в какой группе Штатка_ состоит пользователь 
		if ($user_group -like "") #У пользака нет групп 
			{
			Write-HostAndLog "У пользователя < <$user_name>> нет групп Штатка_. Инфа из группы < <$group_name>>" "c:\logs\FS\_null.log" 
			}
		elseif($user_group.count -ge 2) #У пользователя 2 и более группы штат 
			{
			Write-HostAndLog "У пользователя < <$user_name>> 2 и более группы Штатка_. Инфа из группы < <$group_name>>" "c:\logs\FS\_double.log" 
			} 
		else 
			{
			Add-ADPrincipalGroupMembership $user_group.name -MemberOf $group_name #добавляем группу пользователя в группу FS 
			$gpname = $user_group.name 
			Write-HostAndLog "Добавляем группу пользователя < <$gpname>> в группу < <$group_name>>" $group_name_new_full 
			Remove-ADGroupMember $group_name $user -Confirm:$false #Удаляем пользака из группы 
			Write-HostAndLog "Пользователь < <$user_name>> удален из группы < <$group_name>>" $group_name_new_full 
			}
		}
	}
}

Вам понравиться