2017-10-11 8 views
0

ネットワーク上のすべてのユーザーが、インストールが必要な証明書を含むSMB共有に読み取りアクセス権を持っています。また、このコードをドメイン管理者として実行しています。このエラーを克服するためには何が必要ですか?Invoke-Commandインポート - 証明書アクセスが拒否されました

Access is denied. 0x80070005 (WIN32: 5 ERROR_ACCESS_DENIED) 

これは、各サーバーに証明書をインストールするコードです。

$vms = "App1","App2","App3" 

Invoke-Command -ComputerName $vms -ScriptBlock { 
    Import-Certificate ` 
     -FilePath \\dc1\CertificateShare\17C37D0A655B89967398C9E7E8185F78541B1589.cer ` 
     -CertStoreLocation 'Cert:\LocalMachine\Root' 

} 
+0

を動作するはずです「*このエラーを克服するために何が必要です*?」 - ダブルホップ認証の問題を修正。可能な複製の[Powershell Serverネットワークドライブ](https://stackoverflow.com/questions/24903878/powershell-server-network-drive) – TessellatingHeckler

答えて

0

ダブルホップの問題が発生しました。要するに、同じWindows認証を使用してリモートセッションに別の外部リソースにアクセスするように要求しています。

マイクロソフトでは、セキュリティ上の理由から、これを既定で許可していません。

Double hop issue

あなたはそれについての詳細を読みたい場合は、私の全体のポスト、それは主に、Kerberos認証とどのように関係しているので、解決策はないユニークdefinetely簡単ではないPowerShell remoting caveats

をお読みくださいドメインコントローラはこれを制御したいと考えています。たとえば、ドメインコントローラーは、特定のダブルホップが2つのサーバー間で許可されていることを指定するか、サーバーごとにダブルホップを許可する必要があります。

より良い解決策はドメイン構成ですが、ドメイン管理者に連絡し、彼に納得させる必要があります。

スクリプトリファレンスで、サーバーごとにこれを行う方法を示します。たとえば、上記の画像から、ServerAを設定して、資格情報の委任をServerBに許可する必要があります。

ビルドした自動化リポジトリでは、これらの問題を解決する必要がありました。オートメーションの名前はISHBootstrapで、このリポジトリのスクリプトを参照します。すべてがここに収まるわけではありません。すべてのスクリプトは、ローカルまたはリモートで実行できるので、Invoke-CommandInvoke-CommandWrapのラッパーコマンドレットを使用していることに気付くはずです。尊敬されているスクリプトブロックを調べ、コードを抽出するだけです。

まず、ServerAに2つの前提条件をインストールする必要があります。

私はこのスクリプトInstall-WinRMPrerequisites.ps1を使用するが、それはその後、我々はWSManCredSSPを有効にして設定する必要が

Get-WindowsFeature |Where-Object -Property Name -EQ "WinRM-IIS-Ext"|Add-WindowsFeature 

、このコマンドと同じくらい簡単です。これはセキュアなリモートセッションを必要とするため、ssl経由でwinrmをセットアップする必要があります。このスクリプトは、プロセス全体を実行します。Enable-WSManCredSSP.ps1

  1. WSManCredSSPを有効にします。
  2. 自己署名証明書をインストールし、安全なエンドポイントでWSManを構成します。
  3. WSManを再起動します。
  4. ファイアウォールポートを開きます。ServerAは別のサーバーに認証を委任する準備ができているが、クライアントが明示的にリモートセッションがなければならないことを述べる必要がある。この時点で

    #region Enable WSManCredSSP 
    Enable-WSManCredSSP -Role Server -Force | Out-Null 
    #endregion 
    
    #region Configure a secure WinRMListener 
    $winRmListeners=& winrm enumerate winrm/config/listener 
    $httpsLine= $winRmListeners -match "HTTPS" 
    Write-Debug "httpsLine=$httpsLine" 
    if(-not $httpsLine) 
    { 
        $certificate=Get-ChildItem -Path Cert:\LocalMachine\My |Where-Object -Property Thumbprint -EQ $Thumbprint 
        $hostname=(($certificate.Subject -split ', ')[0] -split '=')[1] 
        Write-Debug "Adding winrm https listener" 
        & winrm create winrm/config/Listener?Address=*+Transport=HTTPS "@{Hostname=""$hostname"";CertificateThumbprint=""$Thumbprint""}" 
        Write-Verbose "Added winrm https listener" 
    
        Write-Debug "Configuring ACL" 
        # Specify the user, the permissions and the permission type 
        $permission = "NETWORK SERVICE","Read,FullControl","Allow" 
        $accessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission; 
    
        $keyPath = $env:ProgramData + "\Microsoft\Crypto\RSA\MachineKeys\"; 
        $keyName = $certificate.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName; 
        $keyFullPath = Join-Path $keyPath $keyName; 
    
        # Get the current acl of the private key 
        # This is the line that fails! 
        $acl = Get-Acl -Path $keyFullPath; 
    
        # Add the new ace to the acl of the private key 
        $acl.AddAccessRule($accessRule); 
    
        # Write back the new acl 
        Set-Acl -Path $keyFullPath -AclObject $acl; 
        Write-Verbose "Configured ACL" 
    } 
    else 
    { 
        Write-Warning "winrm https listener detected. Skipped" 
    } 
    #endregion 
    
    #region restart WinRm service 
    Write-Debug "Restarting winrm service" 
    Get-Service -Name WinRM |Restart-Service| Out-Null 
    while((Get-Service -Name WinRM).Status -ne "Running") 
    { 
        Start-Sleep -Milliseconds 500 
    } 
    Write-Verbose "Restarted WINRM service" 
    #endregion 
    
    
    #region Configure windows firewall 
    $ruleName="WinRM-HTTPS" 
    $rulePort=5986 
    Write-Debug "Querying if firewall port for winrm https is open" 
    if(-not (Get-NetFirewallRule|Where-Object {($_.DisplayName -eq $ruleName) -and ($_.Direction -eq "Inbound")})) 
    { 
        Write-Verbose "Adding firewall port for winrm https is open" 
        New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Action Allow -Protocol "TCP" -LocalPort $rulePort|Out-Null 
    } 
    Write-Host "Winrm https firewall port is ok"   
    #endregion 
    

    :ここ

は、スクリプトから抽出されたコードですこれを可能にする。 CredSSP認証タイプを使用している場合、この

$session=New-PSSession -ComputerName $Computer -Credential $Credential -UseSSL -Authentication Credssp 

お知らせのような二つの重要な事柄を、セッションを作成します。

  • -Credentialsが明示的に彼らがログオンしているのと同じユーザのためであっても指定しなければなりません。
  • -UseSSLを使用すると、winrm secureを使用できます。

は、今すぐあなたの元のコードで$sessionを使用して、それは

Invoke-Command -ComputerName $vms -Session $session -ScriptBlock { 
    Import-Certificate ` 
     -FilePath \\dc1\CertificateShare\17C37D0A655B89967398C9E7E8185F78541B1589.cer ` 
     -CertStoreLocation 'Cert:\LocalMachine\Root' 

} 
関連する問題