Невозможно подключить iPad к Рабочей области (Workplace Join)


Вчера с коллегой ломали голову над проблемой: после установки AD FS 3.0 системы с Windows 8.1 подключались нормально к Рабочей области, а вот iPad ни в какую не хотел.

После всевозможных плясок нашли статью:

«Profile Installation Failed» error when iOS device is Workplace Joined by using DRS on a Windows Server 2012 R2-based server

Как только установили обновление на сервер с AD FS, все заработало – iPad подключился к Рабочей области.

Причина – какие-то просроченные сертификаты от Apple, которые присутствуют на iPad.

Powershell – список групп и их членов


Иной раз надо проанализировать состав групп AD, и возникает достаточно простая задачка: вывести список членов заданных групп с указанием имени группы для каждого члена.

Сделать это несложно, но в Powershell 4 это можно сделать красиво в одну строчку, если использовать новую возможность – переменную конвейера (pipelinevariable):

$a=Get-ADGroup -Filter {Name -like "G_Tasks_Monitoring_FNV-Maps_*"} -PipelineVariable a1 `
| Get-ADGroupMember `
| % { Add-Member -InputObject $_ -Name GroupName -Value $a1.Name -MemberType NoteProperty -force -PassThru } `
| select GroupName,name,SamAccountName

Либо тоже самое с выводом во внешний файл:

$a=Get-ADGroup -Filter {Name -like "G_Tasks_Monitoring_FNV-Maps_*"} -PipelineVariable a1 `
| Get-ADGroupMember `
| % { Add-Member -InputObject $_ -Name GroupName -Value $a1.Name -MemberType NoteProperty -force -PassThru } `
| select GroupName,name,SamAccountName `
| sort groupname `
| Export-Csv -NoTypeInformation .\out.txt -Encoding Unicode

Проверка установленных версий .Net


Учитывая актуальность версии .Net на серверах Exchange (Exchange Server 2013 и .Net), иной раз бывает нужно быстро посмотреть, какая версия .Net стоит и с какими обновлениями.

Вот скрипт переделанный на основе кода взятого с MSDN:

$Source = @" 
using System;
using Microsoft.Win32;

public class dotNetVersions
{
public static void GetUpdateHistory()
{
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"
SOFTWARE\Microsoft\Updates"))
{
foreach (string baseKeyName in baseKey.GetSubKeyNames())
{
if (baseKeyName.Contains("
.NET Framework") || baseKeyName.StartsWith("KB") || baseKeyName.Contains(".NETFramework"))
{

using (RegistryKey updateKey = baseKey.OpenSubKey(baseKeyName))
{
string name = (string)updateKey.GetValue("
PackageName", "");
Console.WriteLine(baseKeyName + "
" + name);
foreach (string kbKeyName in updateKey.GetSubKeyNames())
{
using (RegistryKey kbKey = updateKey.OpenSubKey(kbKeyName))
{
name = (string)kbKey.GetValue("
PackageName", "");
Console.WriteLine("
" + kbKeyName + " " + name);

if (kbKey.SubKeyCount > 0)
{
foreach (string sbKeyName in kbKey.GetSubKeyNames())
{
using (RegistryKey sbSubKey = kbKey.OpenSubKey(sbKeyName))
{
name = (string)sbSubKey.GetValue("
PackageName", "");
if (name == "
")
name = (string)sbSubKey.GetValue("
Description", "");
Console.WriteLine("
" + sbKeyName + " " + name);

}
}
}
}
}
}

}
}
}
}

public static void GetVersionFromRegistry()
{
// Opens the registry key for the .NET Framework entry.
using (RegistryKey ndpKey =
RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "
").
OpenSubKey(@"
SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
{
// As an alternative, if you know the computers you will query are running .NET Framework 4.5
// or later, you can use:
// using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
// RegistryView.Registry32).OpenSubKey(@"
SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
foreach (string versionKeyName in ndpKey.GetSubKeyNames())
{
if (versionKeyName.StartsWith("
v"))
{

RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
string name = (string)versionKey.GetValue("
Version", "");
string sp = versionKey.GetValue("
SP", "").ToString();
string install = versionKey.GetValue("
Install", "").ToString();
if (install == "
") //no install info, must be later.
Console.WriteLine(versionKeyName + "
" + name);
else
{
if (sp != "
" && install == "1")
{
Console.WriteLine(versionKeyName + "
" + name + " SP" + sp);
}

}
if (name != "
")
{
continue;
}
foreach (string subKeyName in versionKey.GetSubKeyNames())
{
RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
name = (string)subKey.GetValue("
Version", "");
if (name != "
")
sp = subKey.GetValue("
SP", "").ToString();
install = subKey.GetValue("
Install", "").ToString();
if (install == "
") //no install info, must be later.
Console.WriteLine(versionKeyName + "
" + name);
else
{
if (sp != "
" && install == "1")
{
Console.WriteLine("
" + subKeyName + " " + name + " SP" + sp);
}
else if (install == "
1")
{
Console.WriteLine("
" + subKeyName + " " + name);
}

}
string Release = subKey.GetValue("
Release", "").ToString();
if (Release != "
") // Release info.
Console.WriteLine( "
" + "Release " + Release);

}

}
}
}

}


}



"
@

$Comment = @"

Value of the Release DWORD Version

378389`t .NET Framework 4.5
378675`t .NET Framework 4.5.1 installed with Windows 8.1
378758`t .NET Framework 4.5.1 installed on Windows 8, Windows 7 SP1, or Windows Vista SP2
379893`t .NET Framework 4.5.2
"
@

Add-Type -TypeDefinition $Source -Language CSharp

[dotNetVersions]::GetUpdateHistory()

[dotNetVersions]::GetVersionFromRegistry()

$Comment

 

Полезные ссылки:

Installing the .NET Framework 4.5, 4.5.1, and 4.5.2

How to: Determine Which .NET Framework Versions Are Installed

.NET Framework Versions and Dependencies

http://gallery.technet.microsoft.com/scriptcenter/DemoofcallingCand-6ef0cd2b

Exchange Server 2013 и .Net


В настоящее время многие компоненты Exchange Server 2013 переписаны на .Net, и поэтому Exchange сильно зависит от него. Так же важна версия .Net.

В документации по установке Exchange RTM указано, что нужен как минимум .Net 4.5. В SP1 (CU4) требуется, чтобы вы установили обновление и довели версию .Net до 4.5.1. С момента выхода SP1 (CU4) ситуация немного изменилась: теперь рекомендуется обновить версию .Net до 4.5.2.

К сожалению пока нет чёткого механизма, чтобы определить, когда и какие обновления .Net можно ставить, чтобы не убить Exchange целиком или какую-то его функциональность.

Дополнение 1:

На текущий момент обновления .Net тестируются с находящимся в разработке CU. Это означает, что вы можете смело устанавливать обновления .Net вышедшие примерно (до) за месяц до выхода конкретного CU. Все более поздние обновления .Net будут протестированы только в следующем CU. Их установка является риском, и вам нужно чётко понимать стоит ли их ставить сразу или подождать.

Дополнение 2:

Ситуация особенно неприятна в отношении обновлений безопасности. CU выходят раз в три месяца, плюс примерно месяц нам нужно на его установку – получается, что обновление безопасности будет установлено только через четыре месяца после выхода, в то время как рекомендуемое время установки обновлений безопасности сейчас не более двух месяцев. Так что ставим, но учитываем риск.

Полезные ссылки:

1. MAPI over HTTP (Требует .Net 4.5.1)

2. .NET Framework Versions and Dependencies

3. Exchange 2013 prerequisites

Как нацелить политику на виртуальные машины?


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

Обычно учётные записи виртуальных машин размещают от отдельной ветке OU и назначают им специальные политики. Но это не всегда удобно, т.к. может привести к дублированию политик, усложнению структуры AD, усложнению делегирования прав. Возникает ситуация аналогичная дуальности архитектуры: вы же не разделяете скорее всего 32-х и 64-х битные компьютеры по разным веткам AD, почему это надо делать для виртуальных и физических машин?

Собственно задача в том, чтобы выполнить групповую политику исключительно на виртуальных машинах в случае, когда их учётные записи лежат в тех же контейнерах AD, что и учётные записи физических машин.

С теоретической точки зрения невозможно определить из программы, что она выполняется в виртуальной среде. На практике не всё так плохо, т.к. производители систем виртуализации (гипервизоров) эмулируют вполне определенные аппаратные устройства и присваивают им «хорошо известные» значения некоторых свойств, которые доступны виртуальной машине.

Проверить эти значения можно с помощью WMI запросов:

Get-WmiObject -Query «select * from Win32_BIOS» -ComputerName testcomp

Например для Microsoft Virtual Server 2005:

SMBIOSBIOSVersion : 080002

Manufacturer : American Megatrends Inc.

Name : BIOS Date: 02/22/06 20:54:49 Ver: 08.00.02

SerialNumber : 0197-5009-1700-0693-8099-8415-07

Version : A M I — 2000622

Ключевое значение тут «A M I».

Для VMware ESX:

SMBIOSBIOSVersion : 6.00

Manufacturer : Phoenix Technologies LTD

Name : PhoenixBIOS 4.0 Release 6.0

SerialNumber : VMware-42 32 41 66 15 d5 15 20-92 ea b4 7a 95 7e f2 17

Version : INTEL — 6040000

Ключевое значение тут «VMware».

Более полный список условий можно найти в опубликованном скрипте http://gallery.technet.microsoft.com/scriptcenter/Determine-if-a-computer-is-cdd20473

Любое условие из скрипта можно преобразовать в фильтр WMI.

Пример фильтра для VMware:

Get-WmiObject -Query «select * from Win32_BIOS where SerialNumber like ‘%VMware%'» -ComputerName testcomp

Условие может быть сложным (с использованием «or» и «and»). Но на практике вам вряд ли нужны все условия сразу. Более подробно о построении запросов можно почитать в документации WQL Operators в библиотеке MSDN.

Теперь остаётся только прописать фильтр для целой политики (Create WMI Filters for the GPO) или включить его в Group Policy Preferences (WMI Query Targeting).

Простейший путь оптимизации загрузки и входа пользователя


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

Самый жёсткий вариант просадить компьютер это включить политику ожидания готовности сети, назначить несколько могучих логон скриптов для мапинга дисков, установки принтеров и т.п. на основе запросов к домен-контроллерам, а также использовать групповые политики для установки ПО.

Можно ли отказаться от этого традиционного для многих пути и в то же время не оказывать негативное влияние на пользователей? Вполне!

Первое, что надо сделать, это мигрировать логон скрипты на Group Policy Preferences. GPP специально существует для того, чтобы заменить большую часть логон скриптов. Они имеют очень гибкую систему фильтров (Targeting), что позволяет внедрять GPP и заменять существующие логон скрипты постепенно и не спеша. Трудоёмкость процесса низкая – производительность системных администраторов возрастает значительно.

Что делать со скриптами, которые не могут быть заменены средствами GPP? Есть простой путь: запускать подобные скрипты через Планировщик заданий, а сами задания создавать с помощью GPP! На первый взгляд может показаться, что это создаёт больший беспорядок, но фактически, как только эта система заработает, вы убедитесь, что порядка становится больше, обслуживание проще, а поиск неисправностей легче.

Этим же способом можно устанавливать ПО (и удалять его), отказываясь от установки ПО с помощью групповых политик.

В конце этого процесса миграции на GPP остаётся отключить политику ожидания готовности сети и – получить благодарности от пользователей, которые удивятся, насколько быстрее стал грузиться их компьютер и профиль!