如何运行Azure的VM CustomScriptExtension作为域用户? (第2部分) [英] How to run Azure VM CustomScriptExtension as domain user? (part 2)

本文介绍了如何运行Azure的VM CustomScriptExtension作为域用户? (第2部分)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新以解释我的根的问题:如果Azure中具有扩展虚拟机,的,因为他们正在调配的,加入域,并运行脚本,我怎么可以运行一个脚本作为域用户?

该脚本需要以访问文件共享来获取安装文件和其他的脚本,虚拟机模板图像的无分也不能(合理)被上传到Azure的Blob存储和下载为要运行作为域用户配置的一部分。

我一分为二这个问题,因为下半年(重$ P $这里psented)没有得到解决。

我有什么工作是一个PowerShell脚本,需要一个JSON文件来创建一个新的虚拟机; JSON文件包含说明虚拟机加入域并运行自定义脚本。这两个事情发生,但是脚本运行的用户工作组\\ SYSTEM ,因此无法访问网络驱动器。


  • 我怎样才能最适合这样的脚本提供特定的用户凭据?

我试图让脚本都会产生不同的用户的凭据的新的PowerShell会话,但我有一个很难搞清楚的语法 - 我甚至不能让它在我的工作发展工作站。当然,安全性是一个问题,但如果我能得到这个使用加密存储的凭据工作,这可能是可以接受的。

...但不限制你的答案 - 也许有一个的完全的不同的方式去了解这一点,并达到相同的效果。

 参数(
    [转] $ sudo的,#表示我们已经尝试过提升到管理员
    [转] $#苏表示,我们已经尝试切换到域用户
)尝试{    #伪常数
    $ DevOrProd =(GET-项目$ MyInvocation.MyCommand.Definition).Directory.Parent.Name
    $ PsScriptPath =拆分路径-parent $ MyInvocation.MyCommand.Definition
    $ pathOnPDrive =\\\\ dkfile01 \\ P \\ SoftwareTestData \\天青\\自动化\\ $ DevOrProd \\运行一次
    $ fileScriptLocal = $ MyInvocation.MyCommand.Source
    $ fileScriptRemote =$ pathOnPDrive \\运行一次从-netdrive.ps1
    #$ filePw =$ pathOnPDrive \\ cred.txt
    $ fileLog =$ PsScriptPath \\开关USER.LOG
    $ MYUSER =莫希干
    $ Myuserpass =阿罕布拉
    $ Mydomainuser =MYDOMAIN \\ $ MYUSER
    $ MYDOMAIN =mydomain.com    #检查变量
    写输出(命令= [$ SUDO])
    写输出(SU = [$ SU])    # 功能
    功能测试 - 管理{
      $的currentUser =新对象Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity] :: GetCurrent())
      返回($ currentUser.IsInRole([Security.Principal.WindowsBuiltinRole] ::管理员))
    }    #主
    写输出(运行一​​次脚本启动...)    #查看管理员权限
    写输出(检查管理员权限......)
    如果(测试管理员){
        写输出( - 是admin。)
    }其他{
        写输出( - 不是管理员)
        如果($ sudo的){
            写输出( - 已经尝试过提升,没有工作。)
            写输出(运行一​​次脚本本地VM完了。)
            写 - 输出()
            出口(0)#不要返回失败退出code,因为Azure的将它仿佛部署爆发报告...
        }其他{
            写输出( - 试图提升......)
            $参数=-noprofile -file $ fileScriptLocal
            $参数= $参数+-sudo
            尝试{
                开始处理powershell.exe -Verb的RunAs -ArgumentList $参数
                写输出( - 新进程启动。)
            } {抓
                写输出( - 新工艺无法启动。)
            }
            写输出(运行一​​次脚本本地VM完了。)
            写 - 输出()
            出口(0)#该行动将继续在衍生的进程
        }
    }
    写输出(经过管理员权限...... [OK])    #查看当前用户
    写输出(检查用户账号......)
    $主机= $([环境] ::计算机名).tolower()
    $域名= $([环境] ::用户域名).tolower()
    $ thisuser = $([环境] ::用户名).tolower()
    写输出( - 当前用户,$域名\\ $ thisuser,上,$主机名。)
    写输出( - 想成为用户,$ MYUSER。)
    如果($ MYUSER -eq $ thisuser){
        写输出( - 正确的用户。)
    }其他{
        写输出( - 错误的用户。)
        如果($ SU){
            写输出( - 已经尝试过转换的用户,没有工作。)
            写输出(运行一​​次脚本本地VM完了。)
            写 - 输出()
            出口(0)#不要返回失败退出code,因为Azure的将它仿佛部署爆发报告...
        }其他{
            写输出( - 尝试切换用户,$ Mydomainuser与passwond$ Myuserpass...)
            #FIXME - 这不工作... :-(
            $ MyuserpassSecure =的ConvertTo-S​​ecureString的$ Myuserpass -AsPlainText -Force
            $证书=新对象System.Management.Automation.PSCredential $ Mydomainuser,$ MyuserpassSecure
            $参数=-noprofile -file $ fileScriptLocal
            $参数= $参数+-sudo -su -Credential $凭证-computername $主机名
            尝试{
                开始处理powershell.exe -Verb的RunAs -ArgumentList $参数
                写输出( - 新进程启动。)
            } {抓
                写输出( - 新工艺无法启动。)
            }
            写输出(运行一​​次脚本本地VM完了。)
            写 - 输出()
            出口(0)#该行动将继续在衍生的进程
        }
    }
    写输出(经过用户帐户... [OK])    从对#执行脚本:驱动器(终于!)
    写输出(试图从对运行脚本:驱动器...)
    写输出( - 脚本文件:$ fileScriptRemote)
    如果(测试路径$ fileScriptRemote){
        写输出(从对行书:驱动器...)
        $参数=-noprofile -file $ fileScriptRemote
        尝试{
            开始处理powershell.exe -Verb的RunAs -ArgumentList $参数
            写输出( - 新进程启动。)
        } {抓
            写输出( - 新工艺无法启动。)
        }
        写输出(运行一​​次脚本本地VM完了。)
        写 - 输出()
        出口(0)#该行动将继续在衍生的进程
    }其他{
        写输出( - 无法找到/进入脚本文件!)
        写输出(从对冉脚本:驱动器... [错误])
    }    写输出(运行一​​次脚本本地VM完了。)
    写 - 输出()} {抓
    写警告(未处理的错误线$($ _ InvocationInfo.ScriptLineNumber):$($错误[0]))
    写输出(异常终止)
    写 - 输出()
}


解决方案

有一对夫妇部分对这个问题的!

首先获得证书存在,在某些时候你会需要一个凭证传递到机器,哪怕是一个凭证,以获得证书。

我个人的解决方案是创建一个证书来加密PSCredential对象,存储一个HTTP服务器上的对象,然后通过在脚本中的证书和PFX密码。当然,如果你是prebuilding服务器,你可以preinstall此证书。 (有一个 code评价的问题与code本)

另外,您可能能够使用像Azure的关键库存储PFX密码。

有关的运行方式的一部分。有几个选项

我没有,因为有关V1推出Powershell的作为不同的用户!所以我希望到这一个别人的会谈。

您可以运行计划任务登录为不同的用户,这应该工作。

如果您是在不同的环境下运行,你可以设置自动登录的属性,重新启动机器,让那么它的脚本运行可删除自动登录条目,并再次重新启动。这使你可以有只能访问你需要它的股份具有从每台机器剥离了它的管理/登录权限,一旦它建成一个特定的严重限制域帐户的好处。这种方式,您也可以将所有构建脚本在Active Directory中,并让该用户将自动拉下来,并运行。

Updated to explain my root problem: If Azure has extensions for VM's, as they are being provisioned, to join a domain, and to run scripts, how can I run a script as a domain user?

The script needs to be run as a domain user in order to access a file share to retrieve installation files and other scripts that are neither part of the VM template image nor can (reasonably) be uploaded to Azure blob storage and downloaded as part of provisioning.

I split this question in two because the 2nd half (represented here) didn't get solved.

What I have working is a Powershell script that takes a JSON file to create a new VM; the JSON file contains instructions for the VM to join a domain and run a custom script. Both things do happen, but the script runs as the user workgroup\system and therefore doesn't have access to a network drive.

  • How can I best provide a specific user's credentials for such a script?

I'm trying to have the script spawn a new Powershell session with the credentials of a different user, but I'm having a hard time figuring out the syntax -- I can't even get it to work on my development workstation. Naturally, security is a concern but if I could get this to work using encrypted stored credentials, this might be acceptable.

... but don't limit your answers -- maybe there's an entirely different way to go about this and achieve the same effect?

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("")
}

解决方案

There's a couple of parts to this question as well!

Firstly getting credentials there, at some point you are going to need to pass a credential to the machine, even if it is a credential to obtain the credentials.

My personal solution is to create a certificate to encrypt a PSCredential object, store that object on a HTTP server, then pass the certificate and pfx password in the script. Of course if you're prebuilding the servers, you can preinstall this certificate. (there is a code review question with the code for this)

Alternatively you might be able to use something like Azure Key Vault to store the pfx password.

For the runas part. There are a few options

I've not launched Powershell as a different user since about v1! so I'll hope somebody else talks about that one.

You could run a scheduled task that logs in as a different user, this should work.

If you're running under a different context you can set the autologin properties, reboot the machine let its scripts run then delete the autologin entry and reboot again. This gives the added benefit that you can have a specific severely limited domain account that only has access to the shares you need it to, that has its admin / login rights stripped from each machine once it is built. This way you can also keep all of your build scripts in Active Directory and let that user automatically pull them down and run.

这篇关于如何运行Azure的VM CustomScriptExtension作为域用户? (第2部分)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆