Автор статьи — Сергей Груздов (egel@egel.su), ведущий инженер, Dataline
Windows Azure Pack предоставляет подписчикам возможность использовать собственные ISO- и VHD(X)-файлы, расположенные в выделенной только для подписчика папке библиотеки. На данный момент единственным способом закачки файлов в эту папку является организация FTP с корневой папкой, указывающей на папку библиотеки, выделенной подписчикам. В данной статье я продемонстрирую, как с помощью ранбуков (runbook) Service Manager Automation (SMA) создавать и удалять папки подписчиков при заведении или удалении пользователя, и как с помощью расширения Microsoft FTP собственными провайдерами авторизации и домашних каталогов авторизовывать пользователей непосредственно через Azure Pack, исключая необходимость дублировать учетные записи в Active Directory.
Подготовка Azure Pack
Предварительно необходимо добавить активы SMA:
- VMMConnection – переменная типа «Соединение», в которой указывается FQDN сервера VMM и учетные данные. Учетная запись должна входить в группу локальных администраторов на сервере библиотеки, сервере VMM и в VMM входить в группу «Администраторы»
- VMMLibPath – переменная с общей папкой корневого каталога библиотеки подписчиков
Ранбуки SMA
Обработка события создания подписчика
Подготовим ранбук для создания каталога подписчика и привязки его к учетной записи в VMM. Текст ранбука ниже. В качестве бонуса – код, оповещающий пользователя после заведения его на админском портале (или любым другим способом) о необходимости смены пароля. Это избавляет от надобности генерации паролей и пересылкой их открытым текстом пользователю.
Notify-Created-User
workflow Notify-Created-User
{
param
(
[Parameter(Mandatory=$true)]
[object] $params
)
$VmmConnection = Get-AutomationConnection -Name 'VmmConnection'
$VmmServerName = $VmmConnection.ComputerName
$SecurePassword = ConvertTo-SecureString -AsPlainText -String $VmmConnection.Password -Force
$VmmCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $VmmConnection.Username, $SecurePassword
$eMail = $params.Name.SubString(0, $params.Name.IndexOf("_"))
$vmmLib = Get-AutomationVariable -Name 'VMMLibPath'
$libServer = $vmmLib.SubString(2)
$libServer = $libServer.SubString(0, $libServer.IndexOf("\"))
$tenantPath = "{0}\{1}" -f $vmmLib, $eMail
Write-Output "Invoke create folder on $libServer"
inlinescript
{
try
{
if (!(Test-Path $Using:tenantPath))
{
Write-Output "Creating folder $($Using:tenantPath)"
New-Item -Type Directory -Path $Using:tenantPath -ErrorAction Stop | Out-Null
}
else
{
Write-Output "Folder $($Using:tenantPath) already exist"
}
}
catch
{
Write-Output $_
}
} –PSComputer $libServer –PSCredential $VmmCredential
inlinescript
{
$tenantSite = "https://my.azureline.ru" # здесь необходимо указать URL Tenant Site
$authSite = "https://auth.azureline.ru" # здесь необходимо указать URL Tenant Auth Site
$mail = $Using:eMail
$roles = Get-SCUserRole -VMMServer $Using:VmmServerName | ?{$_.Name.Contains($mail)}
# Для каждой подписки создается UserRole в SCVMM. Во избежание дубликатов писем, посылаем оповещение только если роль одна (при создании первой подписки)
if (!($roles -is [System.Array]))
{
try
{
[reflection.assembly]::loadwithpartialname("System.Net.Http") | Out-Null
$forget = New-Object System.Net.Http.HttpClient
$getMess = $forget.GetAsync($tenantSite).Result
$getMess.EnsureSuccessStatusCode() | Out-Null
$authPage = $getMess.Content.ReadAsStringAsync().Result
$forgRegex = [regex]'form id="__AjaxAntiForgeryForm".*?__RequestVerificationToken.*?value="(?<Token>.*?)"'
$m = $forgRegex.Match($authPage);
if ($m.Success)
{
$forget.DefaultRequestHeaders.Add("x-ms-client-antiforgery-id", $m.Groups["Token"].Value);
$data = New-Object System.Net.Http.StringContent("{`"emailAddress`":`"$($Using:eMail)`"}", [System.Text.Encoding]::UTF8, "application/json")
$mess = $forget.PostAsync("$authSite/Account/SendMeResetPasswordLink", $data).Result
$mess.EnsureSuccessStatusCode() | Out-Null
Write-Output "Successfuly sent reset password link to $($Using:eMail)"
}
}
catch
{
Write-Output $_
}
Write-Output "Set library share for $($roles.Name). Share path $($Using:tenantPath)"
Set-SCUserRole -UserRole $roles -UserRoleDataPath $Using:tenantPath -VMMServer $Using:VmmServerName | Out-Null
}
else
{
Write-Output "Nothing to do"
}
} –PSComputer $VmmServerName –PSCredential $VmmCredential
}
Очистка каталога FTP
Для очистки каталога FTP от каталогов удаленных подписчиков придется сделать ранбук, выполняющийся по расписанию, так как обработка некоторых событий VMM (нам необходимо для объекта «VMM UserRole» событие «Delete») в данное время в SMA не реализована.
CleanUp-Ftp-Folder
workflow CleanUp-Ftp-Folder
{
$VmmConnection = Get-AutomationConnection -Name 'VmmConnection'
$VmmServerName = $VmmConnection.ComputerName
$SecurePassword = ConvertTo-SecureString -AsPlainText -String $VmmConnection.Password -Force
$VmmCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $VmmConnection.Username, $SecurePassword
$vmmLib = Get-AutomationVariable -Name 'VMMLibPath'
$libServer = $vmmLib.SubString(2)
$libServer = $libServer.SubString(0, $libServer.IndexOf("\"))
$dataPaths = inlinescript
{
$dataPaths = Get-SCUserRole -VMMServer $Using:VmmServerName | %{ $_.UserRoleDataPath }
$dataPaths
} -PSComputer $VmmServerName –PSCredential $VmmCredential
inlinescript
{
$ftpFolders = Get-ChildItem -Directory -Path $Using:vmmLib | %{ $($_.FullName + '\') }
if ($Using:dataPaths -ne $null)
{
$diffList = $ftpFolders | ?{ $Using:dataPaths -notcontains $_ }
}
if ($diffList)
{
foreach ($diff in $diffList)
{
if ([String]::IsNullOrEmpty($diff))
{
continue
}
Write-Output "Deleting $diff"
Remove-Item -Recurse -Force -Confirm:$false -Path $diff
}
}
else
{
Write-Output "Nothing to delete"
}
} –PSComputer $libServer –PSCredential $VmmCredential
}
Данные ранбуки необходимо импортировать, опубликовать, ранбуку «Notify-Created-User» присвоить тэг SPF и привязать к событию «Создать» объекта «SPF-клиент»:
Для ранбука «Cleanup-ftp-folder» необходимо создать расписание, чтобы он выполнялся раз в день:
Подготовка FTP
Необходимо, чтобы службы Framework 2.0/3.5 были предварительно установлены
С помощью диспетчера сервера добавляем роль FTP с поддержкой расширения:
Создаем FTP-сервер:
В качестве пути в мастере указываем физический путь к корню библиотеки подписчиков. Если FTP сервер разворачивается не на сервере библиотеки наилучшим выходом будет создание символической связи с общим ресурсом, например:
mklink /D C:\TenantsData \\vmmlibserver\TenantsData
На следующей странице мастера указываем дополнительные параметры (использование SSL, номер порта и т.д.):
На завершающей странице указываем, что все пользователи имеют право на чтение и запись, но не указываем поддерживаемые типы аутентификации:
На этом первоначальная настройка закончена. Остальные параметры будут указаны после установки модуля расширения.
Установка модуля расширения и настройка FTP
Скачайте приложенный к статье архив «Module.zip» и распакуйте (например, в «C:\Module»). Запустите интерпретатор cmd с правами администратора. Выполните следующие команды (если Ваш FTP называется по другому, укажите его имя в качестве параметра):
Получите следующий вывод:
После этого необходимо исправить файл «CustomFTPHomeDirectoryProvider.dll.config», указав там значения ключей «auth» и «root». Ключ «auth» содержит URL сайта TenantAuth, ключ «root» указывает физический путь к библиотеке подписчиков. Пример:
<configuration>
<appSettings>
<add key="auth" value="https://auth.azureline.ru" />
<add key="root" value="C:\ProgramData\TenantsLibrary" />
</appSettings>
</configuration>
После этого файл «CustomFTPHomeDirectoryProvider.dll.config» необходимо скопировать по физическому пути «C:\Windows\Microsoft.NET\assembly\GAC_MSIL\CustomFTPHomeDirectoryProvider\v4.0_1.0.0.0__a8ad38bd3b2a69ea».
Проверка настроек
Открываем консоль IIS Management, выбираем FTP-сайт, открываем настройку «FTP Authentication». Должен быть включен единственный провайдер аутентификации «CustomAuth»:
Открываем настройку «FTP User Isolation», убеждаемся, что включено «Custom»:
Данная настройка указывает уровень изоляции пользователя. При помощи кастомного провайдера подписчик «запирается» в собственном каталоге.
Теперь тестируем. Я использовал FTP-клиент входящий в FAR. Подключаемся:
Закачиваем файл:
После обновления библиотеки видим загруженный файл:
На портале Azure Pack этот образ теперь можно подключить:
Таким образом, практически без дополнительных усилий, как то, контроль дополнительных учетных записей в AD для доступа к FTP, получилась удобная для подписчика точка загрузки ISO- и VHD(X)-файлов.
Материалы (архивы с готовым модулем, исходниками и ранбуками) можно скачать по этой ссылке. На этом все, до новых встреч!