0

更新解釋我的根本問題:如果天青對虛擬機的,擴展,因爲他們正在供應,加入域,並且運行腳本,我怎麼能運行腳本作爲域用戶?如何以域用戶身份運行Azure VM CustomScriptExtension? (部分2)

該腳本需要作爲域用戶運行才能訪問文件共享以檢索既不是VM模板映像的一部分也不能(合理)上載到Azure blob存儲的安裝文件和其他腳本,以及作爲供應的一部分下載。

我將this question分爲兩部分,因爲下半部分(代表此處)沒有得到解決。

我工作的是一個採用JSON文件創建新VM的Powershell腳本; JSON文件包含虛擬機加入域並運行自定義腳本的說明。兩種情況都會發生,但腳本以用戶workgroup\system運行,因此無法訪問網絡驅動器。

  • 我該如何最好地爲這樣的腳本提供特定用戶的憑據?

我想讓腳本產生一個新的Powershell會話與不同的用戶的憑據,但我很難搞清楚語法 - 我甚至不能讓它工作在我的開發工作站上。當然,安全是一個問題,但如果我可以使用加密的存儲憑證來工作,這可能是可以接受的。

...但不限制你的答案 - 也許有一個完全不同的方式去實現這一目標,並達到相同的效果?

Param(
    [switch]$sudo, # Indicates we've already tried to elevate to admin 
    [switch]$su # Indicates we've already tried to switch to domain user 
) 

try { 

    # Pseudo-constants 
    $DevOrProd=(Get-Item $MyInvocation.MyCommand.Definition).Directory.Parent.Name 
    $PsScriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition 
    $pathOnPDrive = "\\dkfile01\P\SoftwareTestData\Azure\automation\$DevOrProd\run-once" 
    $fileScriptLocal = $MyInvocation.MyCommand.Source 
    $fileScriptRemote = "$pathOnPDrive\run-once-from-netdrive.ps1" 
    # $filePw = "$pathOnPDrive\cred.txt" 
    $fileLog="$PsScriptPath\switch-user.log" 
    $Myuser="mohican" 
    $Myuserpass="alhambra" 
    $Mydomainuser="mydomain\$Myuser" 
    $Mydomain="mydomain.com" 

    # Check variables 
    write-output("SUDO=[$SUDO]") 
    write-output("SU=[$SU]") 

    # Functions 
    function Test-Admin { 
     $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent()) 
     return ($currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) 
    } 

    # Main 
    write-output("Run-once script starting ...") 

    # Check admin privilege 
    write-output("Checking admin privilege ...") 
    if (Test-Admin) { 
     write-output("- Is admin.") 
    } else { 
     write-output("- Not an admin.") 
     if ($sudo) { 
      write-output(" - Already tried elevating, didn't work.") 
      write-output("Run-once script on local VM finished.") 
      write-output("") 
      exit(0) # Don't return failure exit code because Azure will report it as if the deployment broke... 
     } else { 
      write-output(" - Attempting to elevate ...") 
      $arguments = "-noprofile -file $fileScriptLocal" 
      $arguments = $arguments +" -sudo" 
      try { 
       Start-Process powershell.exe -Verb RunAs -ArgumentList $arguments 
       write-output(" - New process started.") 
      } catch { 
       write-output(" - New process failed to start.") 
      } 
      write-output("Run-once script on local VM finished.") 
      write-output("") 
      exit(0) # The action will continue in the spawned process 
     } 
    } 
    write-output("Checked admin privilege ... [OK]") 

    # Check current user 
    write-output("Checking user account ...") 
    $hostname = $([Environment]::MachineName).tolower() 
    $domainname = $([Environment]::UserDomainName).tolower() 
    $thisuser = $([Environment]::UserName).tolower() 
    write-output("- Current user is ""$domainname\$thisuser"" on ""$hostname"".") 
    write-output("- Want to be user ""$Myuser"".") 
    if ($Myuser -eq $thisuser) { 
     write-output(" - Correct user.") 
    } else { 
     write-output(" - Incorrect user.") 
     if ($su) { 
      write-output(" - Already tried switching user, didn't work.") 
      write-output("Run-once script on local VM finished.") 
      write-output("") 
      exit(0) # Don't return failure exit code because Azure will report it as if the deployment broke... 
     } else { 
      write-output(" - Attempting to switch to user ""$Mydomainuser"" with passwond ""$Myuserpass"" ...") 
      # FIXME -- This does not work... :-(
      $MyuserpassSecure = ConvertTo-SecureString $Myuserpass -AsPlainText -Force 
      $credential = New-Object System.Management.Automation.PSCredential $Mydomainuser, $MyuserpassSecure 
      $arguments = "-noprofile -file $fileScriptLocal" 
      $arguments = $arguments +" -sudo -su -Credential $credential -computername $hostname" 
      try { 
       Start-Process powershell.exe -Verb RunAs -ArgumentList $arguments 
       write-output(" - New process started.") 
      } catch { 
       write-output(" - New process failed to start.") 
      } 
      write-output("Run-once script on local VM finished.") 
      write-output("") 
      exit(0) # The action will continue in the spawned process 
     } 
    } 
    write-output("Checked user account ... [OK]") 

    # Run script from P: drive (finally!) 
    write-output("Attempting to run script from P: drive ...") 
    write-output("- Script file: ""$fileScriptRemote""") 
    if (test-path $fileScriptRemote) { 
     write-output("Running script from P: drive ...") 
     $arguments = "-noprofile -file $fileScriptRemote" 
     try { 
      Start-Process powershell.exe -Verb RunAs -ArgumentList $arguments 
      write-output(" - New process started.") 
     } catch { 
      write-output(" - New process failed to start.") 
     } 
     write-output("Run-once script on local VM finished.") 
     write-output("") 
     exit(0) # The action will continue in the spawned process 
    } else { 
     write-output("- Could not locate/access script file!") 
     write-output("Ran script from P: drive ... [ERROR]") 
    } 

    write-output("Run-once script on local VM finished.") 
    write-output("") 

} catch { 
    write-warning("Unhandled error in line $($_.InvocationInfo.ScriptLineNumber): $($error[0])") 
    write-output("ABEND") 
    write-output("") 
} 

回答

0

有這個問題了幾個零件,以及!

首先在那裏獲取憑證,在某些時候,您將需要將憑證傳遞給機器,即使它是憑證以獲取憑證。

我個人的解決方案是創建一個證書來加密PSCredential對象,將該對象存儲在HTTP服務器上,然後在腳本中傳遞證書和pfx密碼。當然,如果你正在建立服務器,你可以預先安裝這個證書。 (有一個code review question與此代碼)

或者,您可能能夠使用類似Azure密鑰保管庫來存儲pfx密碼。

對於runas部分。有幾個選項

我還沒有推出Powershell作爲一個不同的用戶,因爲大約v1!所以我希望別人談論那個。

您可以運行以不同用戶身份登錄的計劃任務,這應該有效。

如果您在不同的環境下運行,您可以設置自動登錄屬性,重啓機器讓其腳本運行,然後刪除自動登錄項並重新啓動。這帶來了額外的好處,即您可以擁有一個特定的嚴格限制的域帳戶,該帳戶只能訪問您所需的共享資源,並且每次創建後都會從每臺計算機上剝離其管理員/登錄權限。這樣,您還可以將所有構建腳本保留在Active Directory中,並讓該用戶自動將其拉下並運行。

+0

1)我以爲我可以在腳本本身存儲一個(hashed/encrypted/rot13'd)密碼_來生成憑證。你是否在說,_無論如何,用戶必須按Enter鍵進入UAC提示?如果是這樣,這種方法在水中死亡。 – KlaymenDK

+0

2)'帳戶是敏感的......' - 恐怕我不知道這是什麼意思。 :-( – KlaymenDK

+0

3)我確實需要「成爲域用戶」才能連接到文件共享。默認用戶'workgroup \ system'(爲什麼不是至少我在JSON中指定的管理員?)沒有權限。 – KlaymenDK

相關問題