web-dev-qa-db-ja.com

管理者としてエージェントからPowershellスクリプトを実行する

SQL Serverサービスの開始時に、サーバーのIIS=でAppPoolをリサイクルする必要があります。

私が取っているルートは、Powershellジョブステップを持つエージェントジョブを実行するスタートアップストアドプロシージャを持つことです。

アプリプールをリサイクルするPowerShellスクリプトをインターネットから作成/取得しました。

# Load IIS module:
Import-Module WebAdministration
# Set a name of the site we want to recycle the pool for:
$site = "Default Web Site"
# Get pool name by the site name:
$pool = (Get-Item "IIS:\Sites\$site"| Select-Object applicationPool).applicationPool
# Recycle the application pool:
Restart-WebAppPool $pool

これはOSレベルで機能しますが、Powershellが管理者として実行されている場合のみです(AdminグループのようにWindowsにログインしているアカウントでも)。

案の定、上記のコードを含むPowershellステップを使用してエージェントでジョブを作成すると、実行時にエラーが発生します

PowerShellスクリプトの6行目でジョブステップがエラーを受け取りました。対応する行は '$ pool =(Get-Item "IIS:\ Sites\$ site" | Select-Object applicationPool).applicationPool'です。スクリプトを修正し、ジョブを再スケジュールしてください。 PowerShellによって返されるエラー情報は次のとおりです: 'コマンドレットの動的パラメーターを取得できません。ファイル名:redirection.configエラー:権限が不十分なため、構成ファイルを読み取れません。プロセス終了コード-1。ステップは失敗しました。

したがって、SQL Serverエージェントから「管理者として実行」する方法が必要です

私はOSレベルで、昇格したアクセス許可で元のスクリプトを実行する新しいスクリプトを作成することに成功しました。

If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
  # Relaunch as an elevated process:
  Start-Process powershell.exe "-File",('"{0}"' -f $MyInvocation.MyCommand.Path) -Verb RunAs
  exit
}
# Now running elevated so launch the script:
& "d:\path\to\my\script.ps1"

これにより、昇格されていないCMDプロンプトまたは昇格されていないPowershellプロンプトのいずれかから新しいスクリプトを実行できます。ただし、PowershellステップまたはCMDステップとしてエージェントから実行しようとすると、

Machine-defaultのアクセス許可設定では、CLSID {longguidhere}およびAPPID {longguidhere}のCOMサーバーアプリケーションのローカルアクティベーションアクセス許可は、アプリケーションコンテナーで実行されているアドレスLocalHost(LRPCを使用)からユーザーNT SERVICE\SQLSERVERAGENT SID(longguidhere)に付与されません使用できないSID(使用不可)。このセキュリティ権限は、コンポーネントサービス管理ツールを使用して変更できます。

私も試しました

Start-Process powershell -Verb runAs -FilePath "d:\path\to\my\script.ps1"

これも、OSレベルでは機能しましたが、エージェントから実行すると同じエラーが発生しました。

どうすれば入手できますか

a:昇格された特権を必要とせずにアプリプールをリサイクルする

または

b:スクリプトを実行して、SQL Serverエージェントから昇格された特権でアプリプールをリサイクルしますか?

7
SEarle1986

少し時間のかかる作業でしたが、次のようにしてなんとかできました。

  • Windowsタスクスケジューラでスケジュールされたタスクを作成して、アプリプールをリサイクルするPowershellスクリプトファイルを実行します。 「最高の特権で実行」としてマークされていることを確認します
  • 管理者の資格情報を使用して資格情報を作成する
  • プロキシアカウントを作成し、CMDサブシステムに関連付ける
  • スケジュールされたタスクを実行するCMDエージェントジョブを作成します(ジョブステップがプロキシアカウントとして実行されるようにします)
  • ジョブを実行するスタートアッププロシージャを作成します。エージェントが実行されているかどうかを確認するwhileループを追加する必要があり、実行されていない場合は5秒待ってから、ジョブの開始を再試行しました
4
SEarle1986

SQL Server資格情報を介して特権Windowsアカウントを使用するSQL ServerエージェントでPowerShellプロキシを作成します。

クレデンシャルの作成 ドキュメント。

プロキシの作成方法

これにより、SQL Serverから直接PowerShellを管理者として実行できます。

資格情報の作成は最初のステップであり、次のようなT-SQLステートメントの実行で構成されます。

CREATE CREDENTIAL MyPowerShellCredential   
WITH IDENTITY = 'DOMAIN\AdministratorAccount'  
    , SECRET = 'AdministratorAccountPassword'  

資格情報を作成したら、SQL Server PowerShellプロキシを作成する必要があります。これはうまくいくはずです:

USE msdb;
EXEC dbo.sp_add_proxy @proxy_name = N'MyPowerShellProxy'
    , @enabled=1
    , @description = N'Proxy used to run PowerShell as an administrator'
    , @credential_name = N'MyPowerShellCredential';

プロキシを作成したら、PowerShellサブシステムで使用できるようにプロキシを有効にする必要があります。このコードはそれを行います:

USE msdb;
EXEC dbo.sp_grant_proxy_to_subsystem @proxy_name = N'MyPowerShellProxy'  
     , @subsystem_name = N'PowerShell'

プロキシを作成したら、PowerShellプロキシを自動的に利用するPowerShellを実行するように構成されたSQL Serverエージェントジョブステップが必要です。

これは、コードを実行するサンプルのSQL Serverエージェントジョブです。

USE [msdb]
GO
DECLARE @jobId binary(16);

EXEC  msdb.dbo.sp_add_job @job_name = N'ResetAppPool'
        , @enabled = 1
        , @notify_level_eventlog = 0
        , @notify_level_email = 2
        , @notify_level_page = 2
        , @delete_level = 0
        , @category_name = N'[Uncategorized (Local)]'
        , @owner_login_name = N'sa'
        , @job_id = @jobId OUTPUT;

EXEC msdb.dbo.sp_add_jobserver @job_name = N'ResetAppPool'
    , @server_name = N'(LOCAL)';

EXEC msdb.dbo.sp_add_jobstep @job_name = N'ResetAppPool'
    , @step_name = N'Step1'
    , @step_id = 1
    , @cmdexec_success_code = 0
    , @on_success_action = 1
    , @on_fail_action = 2
    , @retry_attempts = 0
    , @retry_interval = 0
    , @os_run_priority = 0
    , @subsystem = N'PowerShell'
    , @command = N'# Load IIS module:
Import-Module WebAdministration
# Set a name of the site we want to recycle the pool for:
$site = "Default Web Site"
# Get pool name by the site name:
$pool = (Get-Item "IIS:\Sites\$site"| Select-Object applicationPool).applicationPool
# Recycle the application pool:
Restart-WebAppPool $pool'
    , @database_name = N'master'
    , @flags = 0;

EXEC msdb.dbo.sp_update_job @job_name = N'ResetAppPool'
    , @enabled = 1
    , @start_step_id = 1
    , @notify_level_eventlog = 0
    , @notify_level_email = 2
    , @notify_level_page = 2
    , @delete_level = 0
    , @description = N''
    , @category_name = N'[Uncategorized (Local)]'
    , @owner_login_name = N'sa'
    , @notify_email_operator_name = N''
    , @notify_page_operator_name = N''
GO

ジョブが実行されたときにメールを送信するようにジョブを変更できます。

このエラーに関して、あなたは見ています:

Machine-defaultのアクセス許可設定では、CLSID {longguidhere}およびAPPID {longguidhere}のCOMサーバーアプリケーションのローカルアクティベーションアクセス許可は、アプリケーションコンテナーで実行されているアドレスLocalHost(LRPCを使用)からユーザーNT SERVICE\SQLSERVERAGENT SID(longguidhere)に付与されません使用できないSID(使用不可)。このセキュリティ権限は、コンポーネントサービス管理ツールを使用して変更できます。

これは、ユーザーアカウント制御が管理者承認モードで実行されており、ユーザーに同意を求めるために昇格を必要とするすべてのアクションが必要であることを示しています。 SQL Serverエージェントはサービスとして実行されているため、昇格プロンプトが実行される可能性はなく、したがって失敗します。 NT SERVICE\SQLSERVERAGENTプロンプトを必要とせずにコントロールパネルのコンポーネントサービスアプレットを介してPowerShellを昇格モードでローカルにアクティブ化するアカウント権限。

または、ローカルのAdministratorsグループのメンバーの昇格がnever必要にならないようにWindowsを構成できます。ローカルセキュリティポリシーアプレットを介してそれを行います。次の設定を行います。

  1. Security Settings\Local Policies\Security Optionsフォルダ。
  2. 「ユーザーアカウント制御:ビルトイン管理者アカウントの管理者承認モード」を「無効」に設定します
  3. [ユーザーアカウント制御:管理者承認モードの管理者に対する昇格時のプロンプトの動作]を[プロンプトなしで昇格する]に設定します
  4. [ユーザーアカウント制御:すべての管理者を管理者承認モードで実行する]を[無効]に設定します
6
Max Vernon