Сценарий входа PowerShell в качестве администратора

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

$env:DOMAINNAME
$env:USERNAME
$env:APPDATA
$env:TEMP

И именно поэтому мне нужно, чтобы он запускался при входе в систему, но я думаю, что это проблема с разрешением.

Есть идеи, как я могу это сделать? Я попытался добавить сценарий в раздел Политики конфигурации пользователя, Сценарии входа в систему, и он не сработал, также попробовал в разделе Конфигурация компьютера.

Добавил -ExecutionPolicy Bypass в качестве параметра и все равно ничего.

Я также пытался добавить это как запланированное задание и запустить его как другой пользователь, но все равно не повезло.


person elmizu    schedule 16.05.2018    source источник
comment
Зачем вам нужно запускать сценарий запуска от имени другого пользователя?   -  person Maximilian Burszley    schedule 16.05.2018
comment
Чтобы запустить его как учетную запись с более высокими разрешениями.   -  person elmizu    schedule 16.05.2018
comment
Если вы собираетесь это сделать, вы можете также запустить это как системную учетную запись.   -  person Maximilian Burszley    schedule 16.05.2018
comment
Я только что попытался запустить его с учетной записью NT AUTHORITY\System, и сценарий в конце должен сгенерировать файл, и я действительно сгенерировал файл, но он пуст, это может быть связано с тем, что у него может не быть доступа для импорта модуля AD. но ни одна из машин не будет иметь к нему доступа сейчас, о чем я думаю. Любая другая идея?   -  person elmizu    schedule 17.05.2018
comment
Почему бы ему не иметь доступа к модулю AD? Это зависит от того, включена ли функция RSAT. И я предполагаю, что это присоединенная к домену машина с правами просмотра в AD?   -  person Maximilian Burszley    schedule 17.05.2018
comment
Что нужно сделать в сценарии? Я обычно рекомендую предпочтения групповой политики с нацеливанием на уровне элемента.   -  person Bill_Stewart    schedule 17.05.2018
comment
Это доменная среда, и я открыл powershell с учетной записью пользователя домена, которую использую для тестирования, и попытался импортировать модуль AD. я получил: Import-Module: указанный модуль «activedirectory» не был загружен, потому что ни в одном каталоге модуля не найден действительный файл модуля. В строке: 1 символ: 14 + import-module ‹‹‹‹ activedirectory + CategoryInfo : ResourceUnavailable: (activedirectory:String) [Import-Module], FileNotFoundException + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand .   -  person elmizu    schedule 17.05.2018
comment
@Bill_Stewart скрипты создают подпись пользователя и устанавливают ее по умолчанию в Outlook. я получаю $env:username, чтобы затем выполнить поиск в AD для информации о пользователе, загрузить HTML-шаблон и заменить информацию, чтобы сохранить построенную подпись в $env:appdata и другие вещи, такие как копирование подписи в общую папку, которую другие сценарии позже установили его на Office365   -  person elmizu    schedule 17.05.2018
comment
Если вы хотите использовать модуль ActiveDirectory PowerShell на клиентском компьютере, вы должны сначала загрузить и установить средства удаленного администрирования сервера (RSAT), прежде чем вы сможете включить модуль в разделе Программы и компоненты. В серверных системах RSAT уже присутствует, но вам все равно нужно включить модуль в диспетчере серверов (через Добавить роли и функции).   -  person Ansgar Wiechers    schedule 17.05.2018
comment
Есть ли обходной путь для этого? если нет, это будет означать, что мне придется загрузить его, установить и включить на каждом пользовательском компьютере, который будет 450+, что не учитывается.   -  person elmizu    schedule 17.05.2018
comment
Вы можете получить доступ к AD, используя только классы .NET, но код должен быть переработан.   -  person Bill_Stewart    schedule 17.05.2018


Ответы (1)


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

Модуль ActiveDirectory

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

Используемые вами командлеты — это просто Get-ADUser, Get-ADGroup и Get-ADPrincipalGroupMembership. Это командлеты поиска, использующие протокол облегченного доступа к каталогам (LDAP), поэтому мы можем заменить их собственными функциями поиска, используя классы .NET.

Get-ADUser

Мы можем заменить командлет поиска Get-ADUser нашей собственной функцией, определенной во время выполнения, например так:

function Get-ADUser 
{
    Param ( [string]$Identity = $null )
    IF ($Identity)
    {

        $UserSearcher = New-Object DirectoryServices.DirectorySearcher
        $UserSearcher.SearchRoot = "LDAP://$("DC=$(($ENV:USERDNSDOMAIN).Replace(".",",DC="))")"
        $UserSearcher.Filter = "(&(objectCategory=person)(SAMAccountName=$Identity))"
    
        $UserSearcher.FindAll() | foreach {New-Object PSObject -Property:$_.Properties}
    }
}

Get-ADGroup

Нам также необходимо заменить командлет Get-ADGroup, чтобы мы могли получить группы AD, которые вы указали в своем списке $OfficeLocations.

function Get-ADGroup 
{
    Param ( [string]$Identity = $null )
    IF ($Identity)
    {

        $GroupSearcher = New-Object DirectoryServices.DirectorySearcher
        $GroupSearcher.SearchRoot = "LDAP://$("DC=$(($ENV:USERDNSDOMAIN).Replace(".",",DC="))")"
        $GroupSearcher.Filter = "(&(objectCategory=group)(SAMAccountName=$Identity))"
               
        $GroupSearcher.FindAll() | foreach {New-Object PSObject -Property:$_.Properties}
    }
}

Get-ADPrincipalGroupMembership

Этот командлет не нужно заменять — не потому, что он будет работать сам по себе, а потому, что он вам не нужен для достижения желаемого конечного результата. Вы использовали его для получения членства в группе от пользователя AD, однако у пользователя AD есть список своего членства, прикрепленный к его объекту пользователя AD. Таким образом, по сути, мы можем получить список членства пользователя AD непосредственно из объекта AD User, и мы сделаем это следующим образом:

$userObject = Get-ADUser -Identity $env:USERNAME
$objGroup = $userObject.memberOf

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

Развертывание вашего кода

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

Контекст

Метод, который вы используете для развертывания этого кода, должен соответствовать самому коду. Если ваш скрипт делает предположения о контексте, в котором он работает (например, использует $env:USERNAME для сбора SAMAccountName пользователя для AD), вам необходимо убедиться, что метод развертывания также делает это предположение. Сценарий в том виде, в каком он есть сейчас, делает это предположение — предположение, что это собственный контекст пользователя, запускающий этот код.

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

Зависимости

Теперь мы знаем, что код выполняется от имени пользователя в собственном контексте на машине пользователя, и мы знаем, что код обращается к внешним ресурсам, таким как Active Directory, нам нужно убедиться, что у пользователя есть права на эти зависимости кода имеет, чтобы гарантировать, что код будет работать.

Убедитесь, что вы просмотрели свой код и перечислили все задачи, которые выполняет код. Под этим я подразумеваю, что код будет считывать собственный объект AD пользователя, и он будет считывать сетевое расположение для доступа к файлам подписи, и он будет считывать и записать в собственный реестр пользователя, а также записать в путь к данным приложения пользователя.

В заключение

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

person Adam Parsons    schedule 19.05.2018
comment
Большое спасибо за ответ и помощь в этом вопросе! Это то, что я начну изучать прямо сейчас, но с этим я вижу свет. Как вы заметили в моем скрипте, у меня нет большого опыта работы с powershell, так как я недавно начал учиться, и это самый большой проект, в который я попал. У меня нет опыта вызова классов .NET, но это определенно дает мне представление о том, куда идти дальше, чтобы завершить сценарий. Я буду работать над этим и опубликую результаты для всех, кто помог мне узнать. Благодарю вас! - person elmizu; 21.05.2018