• AD DS – Выбор DC для операции ввода в домен с помощью PowerShell командлета Add-Computer

    imageВ большой доменной инфраструктуре AD DS с большим количеством сайтов можно столкнуться с ситуацией, когда при вводе в домен новых компьютеров в сайте с единственным контроллером RODC операция ввода в домен происходит не на ближайшем RWDC а на отдалённом. Это приводит к тому, что перед тем как можно будет начать использовать в домене такой компьютер, потребуется выждать репликацию от удалённого DC до местного RODC. Избежать данной ситуации можно используя утилиту NETDOM, явным образом указывая ближайший контроллер домена, на котором мы хотим произвести процедуру джойна:

    image

    Но так как по умолчанию в клиентских системах этой утилиты нет, хочется воспользоваться каким-то подручным средством без выполнения дополнительным манипуляций. И тут нам на помощь приходит PowerShell с командлетом Add-Computer… но когда я решил воспользоваться им на практике, то выяснилось что встроенный хелп PowerShell об этом командлете (равно как и сайт TechNet Script Center) о чём-то нам не договаривает.

    Попытка выполнить ввод в домен строго по описанию не сработала, то есть при использовании командлета в виде…

    Add-Computer -DomainName 'MYDOM' -Credential 'MYDOMadmin' -OUPath 'OU=Clients,OU=Branch,DC=mydom,DC=com' -Server 'MYDOMBestDC' -PassThru –Verbose

    … приводила к ошибке, которая фиксировалась в логе NetSetup.LOG (расположен в каталоге C:Windowsdebug) примерно в следующем виде:

    02/03/2011 11:43:51:403 ----------------------------------------------------

    02/03/2011 11:43:51:403 NetpDoDomainJoin

    02/03/2011 11:43:51:403 NetpMachineValidToJoin: 'MyWS001'

    02/03/2011 11:43:51:403    OS Version: 6.1

    02/03/2011 11:43:51:403    Build number: 7600 (7600.win7_gdr.100618-1621)

    02/03/2011 11:43:51:403    SKU: Windows 7 Профессиональная

    02/03/2011 11:43:51:403 NetpDomainJoinLicensingCheck: ulLicenseValue=1, Status: 0x0

    02/03/2011 11:43:51:403 NetpGetLsaPrimaryDomain: status: 0x0

    02/03/2011 11:43:51:403 NetpMachineValidToJoin: status: 0x0

    02/03/2011 11:43:51:403 NetpJoinDomain

    02/03/2011 11:43:51:403    Machine: MyWS001

    02/03/2011 11:43:51:403    Domain: MYDOMBestDCMYDOM

    02/03/2011 11:43:51:403    MachineAccountOU: OU=Clients,OU=Branch,DC=mydom,DC=com

    02/03/2011 11:43:51:403    Account: MYDOMadmin

    02/03/2011 11:43:51:403    Options: 0x23

    02/03/2011 11:43:51:403 NetpLoadParameters: loading registry parameters...

    02/03/2011 11:43:51:403 NetpLoadParameters: DNSNameResolutionRequired not found, defaulting to '1' 0x2

    02/03/2011 11:43:51:403 NetpLoadParameters: DomainCompatibilityMode not found, defaulting to '0' 0x2

    02/03/2011 11:43:51:403 NetpLoadParameters: status: 0x2

    02/03/2011 11:43:51:403 NetpValidateName: checking to see if 'MYDOM' is valid as type 3 name

    02/03/2011 11:43:53:697 NetpCheckDomainNameIsValid for MYDOM returned 0x54b, last error is 0x0

    02/03/2011 11:43:53:697 NetpCheckDomainNameIsValid [ Exists ] for 'MYDOM' returned 0x54b

    02/03/2011 11:43:53:697 NetpJoinDomainOnDs: Domain name is invalid, NetpValidateName returned: 0x54b

    02/03/2011 11:43:53:697 NetpJoinDomainOnDs: Function exits with status of: 0x54b

    02/03/2011 11:43:53:697 NetpDoDomainJoin: status: 0x54b

    Как видно из лога, имя домена формируется как то не совсем адекватно. Немного поигравшись с использованием разных вариантов передачи параметров и проведя аналогию с использованием утилиты NETDOM, был найден работающий вариант, а именно:

    Add-Computer -DomainName 'mydom.comBestDC' -Credential 'MYDOMadmin' -OUPath 'OU=Clients,OU=Branch,DC=mydom,DC=com' -PassThru –Verbose

    То есть вместо параметра Server можно использовать передачу имени DC в параметре DomainName. Данный способ проверен и работает как на Windows 7, так и на Windows XP SP3.

    Если у кого-то есть комментарии по поводу того, как можно ещё обуздать механизм ввода в домен для компьютеров в сайте с RODC будет интересно их здесь услышать.

    Дополнительная информация для размышления:

    Windows Server TechCenter Forums - Selection of DC during a workstation join to domain operation

    Blog Jorge 's Quest For Knowledge! - DC Locator Process in W2K, W2K3(R2) and W2K8 - PART 1

  • Windows Server 2008 R2 – Создание загрузочного USB накопителя

    imageВозникла ситуация, когда пришлось мануально устанавливать ОС Hyper-V Server 2008 R2 на сервер, не имеющий DVD привода. Решил проверить метод, описанный в заметке x(perts)64 Blog - Charlie Russel - HowTo: Make a Bootable USB Disk. Итак, поехали…

    Берём USB накопитель (в моём случае это Kingston DataTravel II 2Gb)…

    image

    В DVD привод устанавливаем загрузочный диск с дистрибутивом Hyper-V Server 2008 R2. Открываем командную строку с правами Администратора и с помощью утилиты DISKPART подготавливаем флэш-накопитель последовательностью команд:

    # Входим в режим работы с утилитой

    DISKPART

     

    # Получаем листинг управляемых дисков

    DISKPART> LIST DISK

     

    # Выбираем флэш накопитель

    DISKPART> SELECT DISK 2

     

    # Производим очистку флэш накопителя

    DISKPART> CLEAN

     

    # Создаем на первичный раздел на всю ёмкость флэш накопителя

    DISKPART> CREATE PARTITION PRIMARY

     

    # Выбираем созданный раздел

    DISKPART> SELECT PARTITION 1

     

    # Делаем выбранный раздел активный

    DISKPART> ACTIVE

     

    # Форматируем активный раздел в формат NTFS

    DISKPART> FORMAT FS=NTFS QUICK

     

    # Назначаем имя диска в системе

    DISKPART> ASSIGN

     

    # Завершаем работу утилиты

    DISKPART> EXIT

    Результат работы утилиты должен выглядеть примерно так:

    image

    После того как флэш накопитель подготовлен, с помощью утилиты BOOTSECT с дистрибутивного диска с ОС производим запись загрузочного сектора в активном разделе накопителя командой:

    D:BOOTBOOTSECT.EXE /nt60 G:

    В этом примере диск D: это DVD диск с дистрибутивом, а G: это USB накопитель.

    image

    Обратите внимание на то, что для 64-битных образов ОС утилита BOOTSECT.EXE должна выполняться в 64-битной среде.

    Далее с помощью утилиты ROBOCOPY копируем всё содержимое дистрибутива ОС с DVD диска на USB накопитель командой:

    ROBOCOPY D: G: /mir

    После завершения процедуры копирования, мы получим готовый к использованию загрузочный USB флэш накопитель:

    image

    В BIOS сервера выставляем загрузку с USB, и если всё сделано правильно, то мы сможем, загрузившись с накопителя, произвести быструю установку ОС. В моём случае полное время установки ОС Hyper-V Server 2008 R2 с учетом перезагрузки сервера заняло 12 минут Улыбка

  • SCCM - Обновление корневых сертификатов

    При попытке развернуть последнюю версию JRE на Windows 7 столкнулся с ситуацией, когда программа установки завершается с ошибкой:

    Имя журнала: Application
    Источник: MsiInstaller
    Дата: 26.01.2011 8:37:12
    Код события: 11330
    Категория задачи: Отсутствует
    Уровень: Ошибка
    Ключевые слова: Классический
    Пользователь: mydomuser
    Компьютер: WS001.mydom.com
    Описание:
    Product: Java(TM) 6 Update 23 -- Error 1330.A file that is required cannot be installed because the cabinet file \sccm-serverSourcesJRE_1.6.0_23x86Data1.cab has an invalid digital signature. This may indicate that the cabinet file is corrupt. Error 266 was returned by WinVerifyTrust.

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

    При этом на компьютерах с Windows XP данной проблемы нет, так как эти ОС получают с WSUS соответствующее обновление - Update for Root Certificates [October 2010] (KB931125)

    clip_image001

    Для того чтобы обеспечить обновление корневых сертификатов на всех клиентских системах Windows можно скачать файл rootsupd.exe и форсированного распространить его. В моём случае, для этой цели я воспользовался SCCM, создав новый пакет распространения:

    clip_image002

    Для пакета сделана соответствующая программа, которая в скрытом режиме будет запускать исполняемый файл rootsupd.exe.

    clip_image001[4]

    После распространения созданного пакета на все точки распространения SCCM и объявления на коллекцию клиентских ПК, проблема с развёртыванием JRE будет исчерпана.

    Для тех, у кого нет возможности использовать SCCM, распространить это обновление можно и другими доступными способами, например через GPO.

  • Powershell - Сброс SusClientId на проблемных клиентах Windows Update в домене

    imageПо мотивам борьбы с проблемой отображения в консоли WSUS некорректно клонированных клиентов, наткнулся на интересную заметку - ShS's Blog - Скрипт для удаленного сброса клиента службы Автоматического обновления. Представленный в этой статье скрипт был взят за основу и несколько переработан. В частности основные переменные были вынесены в отдельный блок, исключено использование временного файла, добавлена обработка исключения возникающего при обращении к 64-битным клиентским ОС, добавлена обработка исключений возникающих при удалении несуществующих ключей реестра, добавлен более детальный вывод хода выполнения скрипта на консоль.

    Скрипт работает в двух режимах, в зависимости от значения переменной $ResetSusClientId. Если значение переменной $ResetSusClientId = 0 (по умолчанию), - производится только сравнение данных о компьютерах полученных из AD и WSUS с выводом информации о значении ключа реестра SusClientId по всем проблемным клиентам. Если значение переменной $ResetSusClientId = 1, производится попытка сброса идентификационной информации клиента WU с последующей его перерегистрацией на сервере WSUS.

    ###############################################################
    # Требования: Powershell 2.0, WSUS API (Добавляется в систему при установке консоли WSUS) 
    #
    Write-Host  'Loading WSUS API...' -ForegroundColor Green
    [reflection.assembly]::LoadWithPartialName('Microsoft.UpdateServices.Administration') 
    Write-Host ''
    #
    # Блок переменных 
    # $WUSrvName – Имя сервера WSUS
    # $WUSrvPort – Порт подключения к серверу WSUS
    # $WUSrvHTTPS – Признак использования шифрования при подключении к серверу WSUS ($true или $false)
    # $ADSearchOU – ADSI путь к контейнеру с доменными учетными записями пользователей (в формате LDAP://distinguishedName)
    # $ADSearchFilter - Фильтр поиска объектов в AD (действующие учетные записи компьютеров)
    # $ResetSusClientId – Признак необходимости форсированной смены идентификатора SusClientId у отсутствующих на WSUS клиентов (1 или 0) 
    #
    $WUSrvName = 'KOM-AD01-SRV-WSUS'
    $WUSrvPort = 8530
    $WUSrvHTTPS = $false
    $ADSearchOU = 'LDAP://OU=Domain Computers,DC=mydom,DC=com'
    $ADSearchFilter = '(&(objectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2))'
    $ResetSusClientId = 0
    #
    # Получаем список всех компьютеров зарегистрированных на WSUS-сервере: 
    Write-Host  'Getting WU clients data from Server' $WUSrvName 'on port' $WUSrvPort '...' -ForegroundColor Green
    $WSUS = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WUSrvName, $WUSrvHTTPS, $WUSrvPort)
    $WSUScomps = $WSUS.GetComputerTargets() 
    $WSUSCompNames = $WSUScomps | ForEach { $_.FullDomainName.ToUpper() } 
    #
    # Получаем список учетных записей компьютеров из Active Directory: 
    Write-Host  'Getting AD computers from OU' $ADSearchOU '...' -ForegroundColor Green
    $ADcomps = (New-Object System.DirectoryServices.DirectorySearcher([ADSI]$ADSearchOU, $ADSearchFilter)).findAll() 
    $ADCompNames = $ADcomps | ForEach {$_.GetDirectoryEntry().dNSHostName.ToString().ToUpper()} 
    #
    # Получаем имена компьютеров, которые есть в Active Directory, но отсутствуют в WSUS:
    Write-Host 'Matching...' -ForegroundColor Green
    $NoWSUSCompNames = $ADCompNames | Where { $WSUSCompNames -notcontains $_ } | Sort-Object
    #
    # Блок смены идентификатора SusClientId 
    If ($NoWSUSCompNames.Count -eq $null) 
    {Write-Host 'Good. No differences.' -ForegroundColor Green}
    Else
    {
    Write-Host 'Found problem computers...' -ForegroundColor DarkRed
    Write-Host ''
    ForEach ($PC in $NoWSUSCompNames)
    {
    $Ping = New-Object System.Net.NetworkInformation.Ping
    Trap {Write-Host $PC 'can not ping' -ForegroundColor DarkRed; continue}
    If ($Ping.send($PC).Status -eq 'Success' ) {
    Write-Host $PC 'available' 
    #
    # Для того чтобы данный метод обращения к удалённому реестру успешно отработал на 64 битных системах скрипт должен запускаться в 64 PS
    # Пример проверки битности - http://poshcode.org/2027
    $is64 = [bool](gwmi win32_operatingsystem -computer $PC | ?{$_.caption -like '*x64*' -or $_.OSArchitecture -eq '64-bit'})
    $isShell32 = [bool]((Get-Process -Id $PID | ?{$_.path -like '*SysWOW64*'}) -or !([IntPtr]::Size -eq 8))
    If ($is64 -and $isShell32)
    {Write-Warning 'Unable to open registry keys because PC is running an x64 OS. Script must be run from a PowerShell x64 shell' }
    Else
    {
    $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $PC)  
    $RegKey= $Reg.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate',$true)  
    $RegKeyValue1 = $RegKey.GetValue('SusClientId')
    #Trap {Write-Host $PC 'can not get registry key value' -ForegroundColor DarkRed; continue}
    Write-Host 'current SusClientId -' $RegKeyValue1
    If ($ResetSusClientId -eq 1) 
    {
    Write-Host 'attempt to reset SusClientId...'
    #
    # Останавливаем на удаленном компьютере службу Windows Update
    Write-Host 'stop Windows Update service (wuauserv)...'
    [System.Reflection.Assembly]::LoadWithPartialName('system.serviceprocess')
    $wuauserv=New-Object System.ServiceProcess.ServiceController('wuauserv',$PC)
    $Stopped=$true
    If ($wuauserv.Status -ne 'Stopped') {
                Try {
                            $wuauserv.Stop()
                            $wuauserv.WaitForStatus('Stopped',(new-timespan -seconds 10))
                            }
                Catch {
                            Write-Warning 'can not stop Windows Update service (wuauserv).'
                            $Stopped=$false
                            }
    }
    #
    # Удаляем идентификационные ключи клиента Windows Update из реестра, предварительно проверив их наличие  
    If ($Stopped) {
                Write-Host 'delete Windows Update registry keys...'
                If($RegKeyValue1 -ne $null){$RegKey.DeleteValue('SusClientId')}
                $RegKeyValue2 = $RegKey.GetValue('SusClientIdValidation')
                If($RegKeyValue2 -ne $null){$RegKey.DeleteValue('SusClientIdValidation')}
                $RegKeyValue3 = $RegKey.GetValue('PingID')
                If($RegKeyValue3 -ne $null){$RegKey.DeleteValue('PingID')}
                $RegKeyValue4 = $RegKey.GetValue('AccountDomainSid')
                If($RegKeyValue4 -ne $null){$RegKey.DeleteValue('AccountDomainSid')}
                $Started=$true 
                }
    #
    # Запускаем на удаленном компьютере службу Windows Update
    Write-Host 'start Windows Update service (wuauserv)...'
    Try {
                $wuauserv.Start()
                $wuauserv.WaitForStatus('Running',(new-timespan -seconds 15))
                }
    Catch {
                Write-Warning 'can not start Windows Update service (wuauserv).'
                $Started=$false
                }
    #
    # Запускаем процедуру перерегистрации клиента Windows Update на сервере WSUS
    If ($Started) {
                Start-Sleep -Seconds 5
                Write-Host 'reset authorization of WU client...'
                $RemoteProcess=([wmiclass]"\$PCrootcimv2:Win32_Process").create('cmd /c wuauclt /resetauthorization /detectnow')
                Write-Host "running return code - $($RemoteProcess.ReturnValue), process ID - $($RemoteProcess.ProcessId)"
                }
    }
    }
    }
    Else 
    { 
    Write-Host $PC 'not available' -ForegroundColor DarkRed }
    Write-Host ''
    }                                 
    }
  • WSUS – Проблемы с клонированными клиентами с дублирующимися SusClientId

    WSUSПри вводе в эксплуатацию партии новых рабочих станций HP с предустановленной ОС Windows 7 Pro OEM столкнулись с ситуацией, когда новые клиентские компьютеры успешно обновлялись с локального сервера WSUS, но при этом не появлялись на консоли WSUS. Вернее сказать, на консоли отображался лишь один новый компьютер, который последним обратился на WSUS. Изучив WindowsUpdate.log на нескольких таких клиентских компьютерах, стало очевидно, что каждый из них использует один и тот же SusClientId, что и приводит к цикличному переписыванию на WSUS сведений о новых клиентах.

    Читать далее...

  • Windows Server 2008 R2 – Добавление скриптов входа на сервере RDS через ключ реестра AppSetup

    imageПри настройке сервера служб Remote Desktop Services (RDS) на Windows Server 2008 R2 c включённым UAC, столкнулся с интересной ситуацией. Стояла такая задача, чтобы при входе в систему для каждого пользователя отрабатывал *.cmd файл, в котором исполнялись бы все необходимые директивы дополнительной настройки пользовательского окружения.

    По старой памяти, запустив редактор реестра от имени Администратора, я открыл ветку реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon и с удивлением обнаружил отсутствие строкового параметра AppSetup (параметр служит для запуска скриптов обеспечения совместимости приложений в многопользовательской среде). Без задней мысли я создал этот параметр, вписал в него имя моего командного файла (USRLOGON_2.CMD), расположенного в папке C:\Windows\System32 и перезагрузил систему. Но к моему удивлению после перезагрузки, при входе пользователей в систему, файл не отрабатывал.

    Читать далее...

  • PowerShell – Сравнение включённых правил брандмауэра на двух компьютерах

    Compare Windows Firewall rules with PowerShellСтолкнулся с ситуацией, когда в разборе полётов у одного из Hyper-V серверов с включенным брандмауэром Windows Firewall потребовалось сравнить  действующие правила с другим сервером. Первое, что пришло в голову - с помощью PowerShell удалённо через вызов Invoke-Command слить правила Windows Firewall с обоих серверов в текстовые файлы и затем сравнить их содержимое.

    Читать далее...

  • PowerShell – Получение информации о локальных пользователях и группах

    Чтобы быстро получить информацию о списке локальных пользователей на удалённом компьютере можно воспользоваться подключением через PowerShell к интерфейсу WMI с запросом в одну строку:

    Get-WmiObject Win32_UserAccount -ComputerName MyPC -Filter "Domain= MyPC'"

    Тоже самое, но уже при обращении к интерфейсу ADSI:

    $computerName = "MyPC"

    $computer = [ADSI]"WinNT://$computerName,computer" 

    $computer.psbase.Children | Where-Object { $_.psbase.schemaclassname -eq 'user' } | Format-Table Name, Description -autoSize

    Если нужно получить информацию с локального компьютера в переменной $computerName укажем значение "."

    По аналогии для получения списка локальных групп безопасности удалённого компьютера используем команду:

    Get-WmiObject Win32_Group -ComputerName MyPC -Filter "Domain='MyPC'"

    ..или

    $computerName = "MyPC"

    $computer = [ADSI]"WinNT://$computerName,computer" 

    $computer.psbase.Children | Where-Object { $_.psbase.schemaclassname -eq 'group' } | Format-Table Name, Description -autoSize

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

    $computerName = "MyPC"

    $computer = [ADSI]"WinNT:// $computerName,computer"

    $computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {

        write-host "Group:" $_.Name

        write-host "Descr:" $_.Description

        write-host "-----"

        $group =[ADSI]$_.psbase.Path

        $group.psbase.Invoke("Members") | foreach {

        $ADSIName = $_.GetType().InvokeMember("AdsPath", 'GetProperty', $null, $_, $null)

            if ($ADSIName -match "[^/]/[^/]") {

            [String]::Join("", $ADSIName.Split("/")[-2..-1])

            }

            else {

            $ADSIName.Split("/")[-1]

            }

        }

        write-host

    }

    Источники информации:

    Janel Blog - Script pour l'énumération des membres d'un groupe

    Powershellcommunity Forum - Listing local user accounts on remote machines

  • Ошибка обработки GPP: Group Policy object did not apply because its targeting item failed with error code 0x86012004

    imageРанее уже описывалась проблема с обработкой Group Policy Preferences (GPP) в части применения нацеливания (Item-level targeting) на OU - Долгая обработка GPP на этапе “Applying Group Policy Drive Maps policy” на клиентах RODC Windows Server 2008 R2

    В ходе дальнейшей эксплуатации GPP для изменения членства группы Администраторов на доменных компьютерах описанная проблема проявила себя по аналогичному сценарию (при нацеливании на доменные OU). Чтобы уйти от этого, приняли решение использовать нацеливание на группы безопасности, то есть изменять членство группы Администраторов в зависимости от членства учетной записи компьютера в той или иной доменной группе безопасности. Однако после настройки GPP и применения на клиентских компьютерах с Windows 7 и Windows Server 2008 R2 обнаружилось, что данная настройка GPP не отрабатывает. Сбор трейсов GPP выявил ошибку обработки типа:

    Failed filter [FilterGroup]. [ hr = 0x86012004 "Клиентское расширение перехватило необрабатываемое исключение "filter expand" в: "Access violation (0xc0000005) occurred at 0xca12dad1; the memory at 0xca12dad1 could not be ????."%100790275" ]

    Как выяснилось, эта проблема известна уже почти год и описана в статье KB976399 - FIX: You cannot apply Group Policy settings on a computer that is running Windows 7 or Windows Server 2008 R2 when security group filters are used in Group Policy preference settings.

    К удивлению для себя выяснил, что данное обновление через WSUS не раскатывалось и для его применения MS предлагает воспользоваться отдельно загружаемым файлом исправления

    Имеющийся на данный момент перечень исправлений включенных в готовящийся к выпуску SP1 для Windows 7 и Windows Server 2008 R2 - Documentation for Windows 7 and Windows Server 2008 R2 Service Pack 1 Release Candidate (KB976932) говорит нам о том, что этот фикс туда включен. Так что ждём релиза SP1, а пока можем выбрать для себя либо вариант с отдельной установкой фикса на проблемных клиентов, либо опять же нужно выбирать альтернативные методы нацеливания.

  • Windows Live Essentials 2011 - 0x80070057

    При попытке установки нового пакета Windows Live Essentials 2011 с сайта Windows Live запускается веб-инсталлятор и если мы работаем через прокси с NTLM авторизацией, то в ходе инициализации процесса установки может возникнуть ошибка настройки инсталлятора

    image

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

    Для тех кто работает за прокси и испытывает подобную проблему нашёл прямую ссылку на дистрибутив полного offline-инсталлятора: Windows Live Essentials 2011 Russian