Архив

Архив раздела ‘Программирование’

Функция определения какие роли хранятся на каких контроллерах домена

8 Сентябрь 2009

В продолжение прошлого поста публикую функцию отображения где какие роли находятся. Я понимаю что подобных скриптов уже полно. НО как говорится хотелось сделать самому, да и разобраться с этим делом. А не использовать безвольно уже готовое.

#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2009.09.07
#   Description:    Функция получения ролей хранящихся на контроллерах домена
#########################################################################################

Function Get-DomainRoles {
    param($domain)
#--- если домен не задан получает текущий домен
    if (!$domain) {
        $domain = (Get-WmiObject -ComputerName '.' -Query 'Select domain From Win32_ComputerSystem').Domain
    }
#--- подключаемся к указанному домену и осуществляем получение информации
    $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext(”Domain”,$domain)
    $dclist = [System.DirectoryServices.ActiveDirectory.DomainController]::findall($context)
#--- разбираем ролученные данные
    Foreach ( $chek in $dclist ) {
#--- отфильтровывает КД на которых нету ролей
        if ($chek.Roles -ne "" ) {
            $i = 0
#--- ну и самое вкусное
            while ($i -ne $chek.Roles.Count) {
                switch ($chek.Roles[$i]) {
                    'SchemaRole' { $role = 'Хозяин схемы' }
                    'NamingRole' { $role = 'Хозяин именования домена' }
                    'PdcRole' { $role = 'Эмуляция главного контроллера домена (PDC)' }
                    'RidRole' { $role = 'Хозяин относительных идентификаторов (RID)' }
                    'InfrastructureRole' { $role = 'Хранитель инфраструктуры' }
                }
                $tmp = "" | Select @{n='Roles';e={$($role)}},@{n='DC';e={$($chek.name.ToLower())}}
                $tmp
                $i++
            }
        }
    }
}

Ну и собственно пример работы:

[PS] <7> C:\Bin>Get-DomainRoles

Roles                                                       DC
-----                                                       --
Эмуляция главного контроллера домена (PDC)                  dc-01.isea.ru
Хозяин относительных идентификаторов (RID)                  dc-01.isea.ru
Хозяин схемы                                                dc-02.isea.ru
Хозяин именования домена                                    dc-02.isea.ru
Хранитель инфраструктуры                                    dc-02.isea.ru


[PS] <8> C:\Bin>
[PS] <8> C:\Bin>Get-DomainRoles -domain "student.isea.ru"

Roles                                                       DC
-----                                                       --
Эмуляция главного контроллера домена (PDC)                  dc-03.student.isea.ru
Хозяин относительных идентификаторов (RID)                  dc-03.student.isea.ru
Хранитель инфраструктуры                                    dc-03.student.isea.ru


[PS] <9> C:\Bin>

Несколько полезных функций на PowerShell

7 Сентябрь 2009

Первая функция получает необходимые свойства объекта из Active Directory

#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2009.09.07
#   Description:    Функция получения свойства объект[а|ов] из Active Directory
#########################################################################################

Function Get-ADProperty  {
    param ($name, $type, $property, $domain)
#--- если не задан домен, то получаем его самостоятельно
    if (!$domain) {
        $domain = ([adsi]"").DistinguishedName
    }
#--- собственно сам фильтр  
    $strFilter = "(&(objectCategory=$type)(cn=$name))"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$domain")
   
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
#--- обозначаем корень поиска
    $objSearcher.SearchRoot = $objDomain
#--- чтоб случайно не задосить Active Directory
    $objSearcher.PageSize = 1000
#--- применяем фильтр
    $objSearcher.Filter = $strFilter
#--- ищем
    $colResults = $objSearcher.FindAll()
#--- выводим результат
    Foreach ($objResult in $colResults) {
        $objResult.Properties.$($property.tolower())
    }

Пример запуска и получаемого результата:

[PS] <25> C:\Bin>Get-ADProperty -type "user" -name "Захарченко Андрей" -property "homeDirectory"
\\balance.isea.ru\homes$\abigor
[PS] <26> C:\Bin>Get-ADProperty -type "group" -name "пользовате*" -property "DistinguishedName" -domain "DC=student,DC=isea,DC=ru"
CN=Пользователи,CN=Builtin,DC=student,DC=isea,DC=ru
CN=Пользователи DCOM,CN=Builtin,DC=student,DC=isea,DC=ru
CN=Пользователи домена,CN=Users,DC=student,DC=isea,DC=ru
CN=Пользователи журналов производительности,CN=Builtin,DC=student,DC=isea,DC=ru
CN=Пользователи системного монитора,CN=Builtin,DC=student,DC=isea,DC=ru
CN=Пользователи удаленного рабочего стола,CN=Builtin,DC=student,DC=isea,DC=ru
[PS] <27> C:\Bin>

Следующая функция получает название текущего домена в формате domain.com

Function Get-Domain {
    (Get-WmiObject -ComputerName '.' -Query 'Select domain From Win32_ComputerSystem').Domain
}

Смена регистра текста

Понадобилось мне приводить название подразделений к стандартизованному виду. Который был заложен еще до меня. В базе по сотрудникам их подразделения написаны все в верхнем регистре. Что согласитесь в Active Directory это бы смотрелось не очень хорошо. По этому у меня появилась необходимость автоматизировать этот процесс. В ходе чего на свет появилась такая функция:

#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2009.07.17
#   Description:    Функция смена регистра подразделений/текста.
#                   Приведение его к общему стандарту.
#########################################################################################

Function Replace-Register ($text) {
#--- в цикле разрезаем текст на слова
    Foreach ($var in  ($text).Split(' ')) {
#--- проверяем если слово состоит из одного символа, делаем нижний регистр
        if ($var.Length -eq 1) {
            $j = $var.ToLower()
        }
#--- если слово разделено "-" то отдельно с ним работаем
        elseif ($var -cmatch '-') {
#--- переключатель
            $switch = 0
#--- разделяем слово по "-"
            Foreach ( $var1 in $var.Split('-')) {
#--- если это первое слово, то в конец добавляем "-"
                if ($switch -eq 0 ) {
                    $j1 = $(($var1.Substring(0,1)).ToUpper()) + $(($var1.Substring(1)).ToLower()) + '-'
                }
                else {
                    $j1 = $(($var1.Substring(0,1)).ToUpper()) + $(($var1.Substring(1)).ToLower())
                }
#--- собираем в строку
                $j = $j + $j1
                $switch++
            }
        }
#--- работа над обычными словами не подошедшими не под один фильтр
        else {
            $j = $(($var.Substring(0,1)).ToUpper()) + $(($var.Substring(1)).ToLower())
        }
#--- собираем текст в строку
        $textuot = $textuot + ' ' + $j
        Remove-Variable j
    }
#--- выводим результат
    $textuot.Trim()
}

Ну и проверим чего у нас получилось:

[PS] <42> C:\>Replace-Register 'ИРКУТСКИЙ И БРАТСКИЙ ТОРГОВО-ЭКОНОМИЧЕСКИЕ КОЛЛЕДЖИ'
Иркутский и Братский Торгово-Экономические Колледжи
[PS] <43> C:\>Replace-Register 'иркутский и братский торгово-экономические колледжи'
Иркутский и Братский Торгово-Экономические Колледжи
[PS] <44> C:\>

Скрипт создания файла экспорта данных для Live@Edu

14 Июль 2009

Наш вуз стал участником программы от Microsoft под название Live@Edu. Это нечто бесплатной почтовой системы с ящиком в 25Gb и в дальнейшем с тесной интеграцией с продуктами Microsoft. При этом в систему можно загрузить необходимых пользователей через csv файл и тем самым завести всех кому необходима данная система. Пока был написан простенький скрипт для генерации csv файла с необходимыми данными внутри и для последующей его отсылки человеку который нас курирует. Так как до 2009.07.01 необходимо было завести не меньше 500 учеток для подтверждения внедрения данного продукта в организации. По этому скрипт очень простой. В дальнейшем он будет дописан и расширен функционал.

#Requires -PSSnapin Quest.ActiveRoles.ADManagement

#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2009.06.28
#   Description:    Экспорт сотрудников в CSV для создания почтовых ящиков в систему Live@Edu
#########################################################################################

#--- функция генерации пароля
Function New-Password ([int]$intPasswordLength){
#--- проверяем что пароль больше 4 символов
    if ($intPasswordLength -lt 4) {return "password cannot be <4 chars"}
#--- наборы символов для генерации
    $strNumbers = "1234567890"
    $strCapitalLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    $strLowerLetters = "abcdefghjkmnpqrstuvwxyz"
    $strSymbols = "!%^&*()+=/?{}[]~,.<>:"

#--- собственно сама генерация пароля
    $rand = new-object random
    for ($a=1; $a -le $intPasswordLength; $a++){
        if ($a -gt 3){
            $b = $rand.next(0,4) + $a
            $b = $b % 3 + 1}
        else { $b = $a }
        switch ($b){
        "1" {$b = "$strNumbers"}
        "2" {$b = "$strCapitalLetters"}
        "3" {$b = "$strLowerLetters"}
        "4" {$b = "$strSymbols"}}
        $charset = $($b)
        $number = $rand.next(0,$charset.Length)
        $RandomPassword += $charset[$number]
    }
    return $RandomPassword
}

#--- объявляем переменные
$SQLServer = "SQLSERVER"
$DBName = "DB_SOTRUDNIC"
$i = 0
$domain = 'bguep.info'

#--- создаем подключение к Microsoft SQL Server
$SQLConnection = new-object System.Data.SqlClient.SqlConnection("Initial Catalog=$DBName;Data Source=$SQLServer;Integrated Security=SSPI")
$SQLConnection.Open()

#--- основной цикл выполнения
ForEach ($user in Get-QADUser -searchroot "OU=БГУЭП,DC=isea,DC=ru" -IncludedProperties WebPage,LogonName,AccountIsDisabled -SizeLimit 0 ) {
#ForEach ($user in Get-QADUser -searchroot "OU=Информационное Управление,OU=БГУЭП,DC=isea,DC=ru" -IncludedProperties WebPage,LogonName,AccountIsDisabled -SizeLimit 0 ) {
    if ($user.webpage){
        if (!($user.webpage -match "^Q")) {
#--- ищем, что пользователь является сотрудником вуза (проверяем по "рег. номеру")
            $query = "SELECT TOP (1) регном FROM dbo.BankCustomer WHERE регном = " + $($user.WebPage -replace "[^0-9 \d]") + ""
            $SQLCommand = New-Object System.Data.SqlClient.SqlCommand($query, $SQLConnection)
            $SQLReader = $SQLCommand.ExecuteScalar()
#--- вытаскиваем должность сотрудника
            $query = "SELECT TOP (1) Должность FROM dbo.Customer WHERE регном= " + $($user.WebPage -replace "[^0-9 \d]") + ""
#--- проверяем, что "рег. номер" не пустой и пользователь не отключен в AD
            if ($SQLReader -and !$user.AccountIsDisabled) {
#--- создаем объект для дальнейщего экспорта
                $export = "" | Select-Object @{name='EmployeeID';expression={$user.webpage}}, `
                                        @{name='FullName';expression={$user.DisplayName}}, `
#                                       @{name='Post';expression={(New-Object System.Data.SqlClient.SqlCommand(("SELECT TOP (1) Должность FROM dbo.Customer WHERE регном= " + $($user.WebPage -replace "[^0-9 \d]") + ""), $SQLConnection)).ExecuteScalar()}}, `
                                        @{name='Email';expression={(($user.LogonName).ToLower() + "@$domain")}}, `
                                        @{name='Password';expression={(New-Password (10))}}
                $export  
                $i++
            }
        }
    }
}

Write-Output "Итого пользователей: $($i)"
$SQLConnection.Close()

Архивирование и удаление mailbox от удаленных почтовых e-mail

Посмотрев на занятое пространство на почтовом сервере под mailbox для почтовых ящиков нескольких доменов. Я понял, что пора наконец сделать инструмент для удаления не используемых mailbox после удаления пользователей из базы e-mail. Раньше, не было в этом необходимости, но место стало поджимать и настало время разобраться. На помощь пришел bash. На нем я написал вот такой маленький скрипт.

#!/bin/sh

#########################################################################################
#   Created:      Zakharchenko Andrey Ruslanovich
#   Date:         2009.05.20
#   Description:  Поиск mailbox для удаленных почтовых ящиков из базы mysql.
#                      Производится поиск, архивирование в папку хранения и удаление.
#                      исходного mailbox
#########################################################################################

#--- объявляем переменные
i=0
domaindir="/var/files/mail"
mailolddir="/var/files/mailold"

#--- проверяем существование архивной папки
if ! test -d ${mailolddir}.
then
    mkdir ${mailolddir}
fi

#--- составляем листинг доменов
for domain in $( ls ${domaindir} ).
do
#--- создаем в архивной папке доменные папки
    if ! test -d ${mailolddir}/${domain}
    then
             mkdir ${mailolddir}/${domain}
    fi

#--- просматриваем содержимое доменных папок и ищем соответствие mailbox в mysql базе
    for email in $( ls ${domaindir}/${domain} )
    do
tmp=`mysql --user=root -p --database=mail-server --execute="select username.
                                                    from users where username='${email}' "
| awk '$1!="username"'`
#--- если пользователя нету в базе, то архивируем mailbox и удаляем исходную папку
             if test -z ${tmp}
             then
                 TMP=`let "i+=1"`
                 echo -e "Archiving item....  \t  domain: $domain mailbox: ${email}"
                 tar -jcf ${mailolddir}/${domain}/${email}.tar.bz2 ${domaindir}/${domain}/${email}
                 echo -e "Remove item.... \t domain: ${domain}, mailmox: ${email}"
                 rm -rdf ${domaindir}/${domain}/${email}
             fi
    done
done

echo -e "It is processed mail boxes \t $i"

#--- ищем архивные ящики которые хранятся больше полугода и удаляем их
find ${mailolddir} -not -newerct '11 week ago' -and -type f  -delete

От решил все необходимы мне задачи :) Так как порой какой-то невменяемы преподаватель появляется через пол года и просит ему по новой создать почтовый ящик и вернуть ему письма. Из-за этого я сначала архивирую mailbox, а только потом удаляю старый mailbox.

Импорт DHCP списка.

Вот таким коротким кодом в одну строку сделал импорт всей резервации.

ForEach ($address in Get-Content dhcp-export.txt) { $tmp = $address.split("`t"); if ($tmp[0] -notmatch "^10\.1\.2\.") {`
netsh dhcp server \\10.1.1.39 scope 10.1.0.0 add reservedip $tmp[0] $tmp[4] $tmp[1]| Out-Null }}

Тут конечно нету ни чего героического. Разместил так, для себя чтоб не забыть.

Ищем уволенных сотрудников в Active Directory через SQL базу

29 Апрель 2009

У меня в организации есть база данных в которой отображается вся миграция сотрудников внутри вуза. Из этой базы мы когда заводим сотруднику учетную запись в Active Directory в поле WebPage заносим ID пользователя. Так, что вот, родился скрипт чтоб вычистить всех уволенных пользователей. Пока он просто на консоль выводит информацию, чтоб инженер мог вручную все просмотреть и принять решение, но его легко можно модифицировать чтоб он сам блокировал/удалял учетную запись пользователя.

param ([switch]$show, [switch]$disable, [switch]$csv)
#########################################################################################
#   Created:      Zakharchenko Andrey Ruslanovich
#   Date:         2009.04.29
#   Description:  Поиск уволенных пользователей в Active Directory через запрос в
#                 к MS SQL серверу
#   Dependencies: Quest.ActiveRoles.ADManagement
#########################################################################################
$SQLServer = "SQLSERVER"
$DBName = "DB_SOTRUDNIC"
$i = 0
$text = "`n
`t Надо использовать следующий синтаксис скрипта:
`t -show        - Выводит информацию на консоль
`t -disable     - Отключает всех уволенных сотрудников
`t -csv         - Выводит информацию в формате для csv
`t------------------------------------------------------------------------------------
`t Пример:
`t ./search-delete-user-from-ad.ps1 -show "


if (!($show) -and !($disable) -and !($csv)) {write-warning $text; return}

$SQLConnection = new-object System.Data.SqlClient.SqlConnection("Initial Catalog=$DBName;Data Source=$SQLServer; `
                                Integrated Security=SSPI"
)
$SQLConnection.Open()
ForEach ($user in Get-QADUser -searchroot "OU=БГУЭП,DC=isea,DC=ru" -IncludedProperties WebPage,LastLogon,ParentContainer, `
                                whenchanged,LogonName,AccountIsDisabled -SizeLimit 0 ) {
    if ($user.webpage){
        if (!($user.webpage -match "^Q")) {
            $query = "SELECT TOP (1) регном FROM dbo.Customer WHERE регном = " + $user.WebPage + ""
            $SQLCommand = New-Object System.Data.SqlClient.SqlCommand($query, $SQLConnection)
            $SQLReader = $SQLCommand.ExecuteScalar()
            if (!$SQLReader) {
                if ($show) {
                    Write-Output "Name: $($user.DisplayName)"              
                    Write-Output "LogonName: $($user.LogonName)"           
                    Write-Output "WebPage: $($user.WebPage)"
                    Write-Output "AccountIsDisabled: $($user.AccountIsDisabled)"               
                    Write-Output "ParentContainer: $($user.ParentContainer)"
                    Write-Output "Whenchanged: $($user.whenchanged)"
                    Write-Output "LastLogon: $($user.LastLogon)"
                    Write-Output "-----------------------------------------------------------------------"
                }
                if ($disable) {
                    If ($user.AccountIsDisabled -eq $false) {
                        ($user).AccountIsDisabled = $true
                        ($user).CommitChanges()
                        Write-Output "Name: $($user.DisplayName) - Отключен"
                        Write-Output "AccountIsDisabled: $($user.AccountIsDisabled)"
                    }
                }
                if ($csv) {
                    $tmp = "" |Select-Object @{name='Name';expression={$($user.DisplayName)}},@{name='LogonName';expression={$($user.LogonName)}}, `
                    @{name='WebPage';expression={$($user.WebPage)}},@{name='AccountIsDisabled';expression={$($user.AccountIsDisabled)}}, `
                    @{name='ParentContainer';expression={$($user.ParentContainer)}},@{name='Whenchanged';expression={$($user.whenchanged)}}, `
                    @{name='LastLogon';expression={$($user.LastLogon)}}
                    Write-Output $tmp
                }
                $i++
            }
        }
    }
}

Write-Output "Итого пользователей: $($i)"
# Out-file -filepath "Пользователи к удалению.txt" -Encoding "Unicode"
$SQLConnection.Close()

Virtualization WMI Provider

21 Апрель 2009

Сегодня я хочу попытаться объяснить как используя PowerShell, можно управлять ролью виртуализации Hyper-v. Пока я для себя вижу такую возможность только через WMI провайдер под названием Virtualization WMI Provider. Знакомство начнем с класса Msvm_ComputerSystem он нам позволит узнать информацию о хост машине и о ВМ созданных на этом сервере. Читать далее…

Автоматизация процесса заведения веб узлов на сервере IIS 7.0

20 Апрель 2009

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

param ($domain, $password, $ipaddress)

#########################################################################################
#   Created:      Zakharchenko Andrey Ruslanovich
#   Date:         2009.04.20
#   Description: Добавление web узла на сервер IIS 7.0.
#                       Создание необходимых пользователей/групп/DNS записей
#             Установка пирмишенов на домашнюю папку сайта
#             Добавление ссылок для DFS
#########################################################################################
$text = "`n
`t Надо использовать следующий синтаксис скрипта:
`t -domain      - Название домена. Пример: domain.isea.ru
`t -password    - Предпологаемый пароль пользователя
`t -ipaddress   - ip адес сервера IIS 7.0
`t------------------------------------------------------------------------------------
`t Пример:
`t ./add-web-iis-site.ps1 -domain "
"domain.isea.ru"" -password ""uRusae8kie"" -ipaddress ""10.1.1.92"" "

if ((!$domain) -or (!$password) -or (!$ipaddress)) { Write-Warning $text; return; }

#--- объявление переменных
$user = "iis-$domain"
$userou = "OU=IIS Servers,OU=Domain Servers,OU=БГУЭП,DC=isea,DC=ru"
$groupou = "OU=Sites,OU=Groups,OU=БГУЭП,DC=isea,DC=ru"
$resourcegroupou = "OU=Sites,OU=Resources,OU=БГУЭП,DC=isea,DC=ru"
$diskmapgroupou = "CN=Sites Disk map (res),OU=Sites,OU=Resources,OU=БГУЭП,DC=isea,DC=ru"
$gp = "Site $domain"
$gpres = "Site $domain (res)"
$dir = "D:\Sites"
$dirhome = join-path $dir $domain
$dnsserver = "dc-02.isea.ru"
$zone = "isea.ru"
$class = 1
$ttl = 3600
$site = "www.$domain"

Write-Host "Загрузка оснастки IIS 7.0. Это может занять некоторое время"
Add-PSSnapin WebAdministration

Write-Host "Загрузка оснастки Active Directory. Это может занять некоторое время"
Add-PSSnapin Quest.ActiveRoles.ADManagement

Write-Host "Подключение к контроллеру домена DC-02. Это может занять некоторое время"
connect-QADService -service 'DC-02.isea.ru' | out-null

#--- создаем пользователя
if ($user.Length -ge 20 ) { $usertmp = $user.Substring(0,20) }
else { $usertmp = $user }
$create = New-QADUser -name $user -ParentContainer $userou -SamAccountName $usertmp  -UserPassword $password -FirstName $user -DisplayName $user -UserPrincipalName "$user@isea.ru"

#--- устанавливаем параметры пользователя
Set-QADUser $create.DN -PasswordNeverExpires $true -ObjectAttributes @{userWorkstations='IIS-02'} | out-null

#--- содаем группу
$gpcreate = New-QADGroup -ParentContainer $groupou -Name $gp -SamAccountName $gp

#--- ресурсную группу
$gprescreate = New-QADGroup -ParentContainer $resourcegroupou -Name $gpres -SamAccountName $gpres  -GroupScope 'DomainLocal'

#--- делаем добавления групп
Add-QADGroupMember -Identity $gprescreate.DN -Member $gpcreate.DN | out-null
Add-QADGroupMember -Identity $diskmapgroupou -Member $gprescreate.DN | out-null

#--- содаем целевую папку и настраиваем пермишины
New-Item $dirhome -type dir | out-null
$acl  = Get-Acl $dirhome
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagationn = [system.security.accesscontrol.PropagationFlags]"None"
$AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule ("isea\$gpres", "Modify",$inherit, $propagationn, "Allow")
$acl.AddAccessRule($AccessRule)
$AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule ("$user@isea.ru", "ReadAndExecute" ,$inherit, $propagationn, "Allow")
$acl.AddAccessRule($AccessRule)
$acl | Set-Acl $dirhome

#— Отключение от контроллера домена DC-02
Disconnect-QADService

#--- заводим записи в DNS
$wmi = [wmiclass]"\\$dnsserver\root\MicrosoftDNS:MicrosoftDNS_AType"
$wmi.CreateInstanceFromPropertyData($dnsserver, $zone, $site, $class, $ttl, $ipaddress) | out-null

$wmi = [wmiclass]"\\$dnsserver\root\MicrosoftDNS:MicrosoftDNS_CNAMEType"
$wmi.CreateInstanceFromPropertyData($dnsserver, $zone, $domain, $class, $ttl, $site) | out-null

#--- содаем web узел
New-Item iis:\Sites\$domain -bindings @{protocol="http";bindingInformation=$ipaddress+":80:$domain"} -physicalPath $dirhome | out-null
Set-ItemProperty -Path "IIS:\Sites\$domain"  -name username -value "ISEA\$usertmp" | out-null
Set-ItemProperty -Path "IIS:\Sites\$domain"  -name password -value $password | out-null

#--- сосздаем линк для DFS и назначаем права
dfsutil Link Add "\\isea.ru\Sites$\$domain" "\\IIS-01\Site$\$domain" | out-null
dfsutil property  acl reset "\\isea.ru\Sites$\$domain" | out-null
dfsutil property  acl grant "\\isea.ru\Sites`$\$domain" 'isea\Sites (res):R' protect | out-null
$tmp = "`"isea\"+$gpreS+'"'+ ':R'
dfsutil property  acl grant "\\isea.ru\Sites`$\$domain"  $tmp | out-null

ToDo
В дальнейшем хочется данный скрипт добавить:
1. возможностью проверки на существование пользователя/группы/веб узла/записей в DNS
2. избавится от страшной и ненужной переменной $tmp
3. найти способ настройки «анонимной проверки подлинности», а то пока вручную приходится прописывать
4. добавить генерацию пароля
—————————————
Предложения и замечания принимаются.

P.S. для для написания скрипта использовались PowerShell Snap-in for IIS 7.0 (x86) для упрвления IIS и PowerShell Commands for Active Directory для работы с AD

Находим у кого размер папки больше установленного значения.

17 Март 2009
Комментарии отключены

Сам скрипт user-dir-size.pl1

param ($path,$size,$diff,$min)
#$diff = "no";
$text = "`n
        `t Надо использовать следующий синтаксис скрипта:                              
        `t -path - путь до домашней папки                                            
        `t -size - размер папки, поддерживается сокращения: Gb,Mb,Kb                
        `t -diff - вычислить кто почти достиг придела в диапазоне: yes|no. Default no
        `t -min  - минимальный размер, используется в паре с -size                  
        `t---------------------------------------------------------------------------
        `t Пример:                                                                  
        `t ./user-dir-size.ps1 -path "
"E:\Homes\"" -size 1Gb                          
        `t ./user-dir-size.ps1 -path "
"E:\Homes\"" -size 1Gb -diff yes -min 900Mb"
 
if ((!$diff) -or ($diff -eq "no")) {
    if (!$path -or !$size ) {
    write-warning $text ;
    return
    }
    else{
Get-ChildItem -LiteralPath $path |  
Where-Object {$_.PSIsContainer} |  
ForEach-Object {  
    $u=$_
    $u | Get-ChildItem -Recurse |
    Measure-Object  Length -Sum |
    Where-Object {($_.sum -gt $size)} |
    Select @{name="Name"; expression={$u.name}},  
        count,  
        @{n="Summ"; e={"{0:n2}Mb" -f ($_.sum/1Mb)}}  
} | ConvertTo-Html -Head " <link rel='stylesheet' href='styles.css' type='text/css' />" |Out-file  "Превышена квота.html"
    }
}
else {
    if ((!$path -or !$size -or !$min) -or ($diff -ne "yes")) {
    write-warning $text ;
    return
    }
    else {Get-ChildItem -LiteralPath $path |  
Where-Object {$_.PSIsContainer} |  
ForEach-Object {  
    $u=$_
    $u | Get-ChildItem -Recurse |
    Measure-Object  Length -Sum |
    Where-Object {($_.sum -gt $min) -and ($_.sum -lt $size)} |
    Select @{name="Name"; expression={$u.name}},  
        count,  
        @{n="Summ"; e={"{0:n2}Mb" -f ($_.sum/1Mb)}}  
}| ConvertTo-Html -Head " <link rel='stylesheet' href='styles.css' type='text/css' />" |Out-file  "Близок к превышению.html"
 
    }
}

Таблица стилей styles.css

body {
background-color: #CCC;
}
body,table,td,th {font-family:Tahoma; color:black;Font-Size;12pt}
th {
font-weight:bold;
background-color: #99F ;
}
td {background-color: white; }
table {
background-color: #000;
text-align: center;
}

Данный скрипт считает общий объем домашней папки и выводи в красивую html табличку тех товарищей, чей объем папки превысил 1Gb места