使用管理员权限在Powershell登录脚本中维护用户环境变量

时间:2018-03-28 04:14:44

标签: powershell windows-server-2016

我不小心从我的AD中删除了180个用户,但他们无法恢复。我在AD中重新创建了帐户,但没有。由于新的SID,这会在登录时在其笔记本电脑上创建新的配置文件。我正在尝试编写一个脚本,授予他们访问旧配置文件文件夹的权限,并在桌面上创建一个快捷方式。

我的脚本运行正常,有一个问题。使用的环境变量最终会引用回运行脚本的管理员帐户。用户自己无权更改旧文件夹的安全性。我需要尝试让环境变量引用用户,但拥有管理员帐户的权限才能重写权限。

到目前为止,这是脚本。我现在正在使用任务计划程序进行部署,这是另一种蠕虫,因为我并不完全了解那里的证书方面。我的意思是理想情况下,任务将作为域管理员运行,执行脚本asap,并让脚本将环境变量解析为登录用户。

$permission = ":(OI)(CI)M"
$sam = $env:USERNAME
$folderName = "C:\Users\$($sam)"

Invoke-Expression -Command ( 'ICACLS $folderName /grant:r $sam$($permission) /t' )

$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\Profile Backup.lnk")
$Shortcut.TargetPath = $folderName
$Shortcut.Save()

它的$ env:USERNAME和$ home变量给我带来麻烦..

或者我还有另一种方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

您可以使用query session命令获取当前登录用户的登录名。然后基于此创建NTAccount对象以检索SIDwin32_userprofile WMI对象以找出配置文件路径。像这样:

$m = query session | Select-String -Pattern "\>console\s*(\S*)\s"
$sam = $m.Matches[0].Groups[1].value

$acc = New-Object System.Security.Principal.NTAccount($sam)
$sid = $acc.Translate([System.Security.Principal.SecurityIdentifier]).Value

$profile = Get-CimInstance -ClassName win32_userprofile -Filter "SID='$sid'"
$folderName = $profile.LocalPath

答案 1 :(得分:-1)

编辑我已经考虑了一夜,所以我会更新答案。您将需要加密域管理员密码,然后用户将运行该脚本。

当这样的事情发生时总是很糟糕。我没有可能尝试这一点,但我认为以下方法是可行的。该脚本要求用户输入密码加密它并以用户身份运行该命令。

第一阶段是让域管理员将其密码加密到文件:

这是由Domain Admin准备的(随PS脚本一起分发) - 我建议在恢复完成后更改密码:

1)Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File 'C:\<script_path>\admin_passwd.txt'

2)这将由用户执行(您必须填写管理员用户ID并使用脚本分发密码文件)。脚本路径可以通过(Get-Location).Path获得。我没有将它添加到源代码中,因此您可以决定如何实现它:

$permission = ":(OI)(CI)M"
$admin= "<your_admin_userid>"
$sam = $env:USERNAME
$domain = $env:UserDomain
$folderName = "C:\Users\$($sam)"

# get domain admin password
$encrypted_passwd = get-content 'C:\<script_path>\admin_passwd.txt' | ConvertTo-securestring

# Setting process invocation parameters.
$process_start_info = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$process_start_info.CreateNoWindow = $true
$process_start_info.UseShellExecute = $false
$process_start_info.RedirectStandardOutput = $true
$process_start_info.RedirectStandardError = $true
$process_start_info.UserName = $admin
$process_start_info.Domain = $domain
$process_start_info.Password = $encrypted_passwd
$process_start_info.Verb = 'runas'
$process_start_info.FileName = 'ICACLS'
$process_start_info.Arguments = "$folderName /grant:r $sam$($permission) /t"

# Creating process object.
$process = New-Object -TypeName System.Diagnostics.Process
$process.StartInfo = $process_start_info

# Start the process
[Void]$process.Start()

$process.WaitForExit()

# synchronous output - captures everything
$output = $process.StandardOutput.ReadToEnd()
$output += $process.StandardError.ReadToEnd()

Write-Output $output


$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\Profile Backup.lnk")
$Shortcut.TargetPath = $folderName
$Shortcut.Save()