【问题标题】:Powershell script as specific userPowershell脚本作为特定用户
【发布时间】:2014-12-04 19:30:57
【问题描述】:

我在以指定用户身份调用 Powershell 脚本时遇到问题,希望有人就如何进行故障排除提供意见。

我有一个功能正常的脚本,可以将文件移动到名为“Move_files.ps1”的网络位置。从 PS 控制台手动运行时,这运行没有问题(我收集它使用我登录的凭据)。

在生产中 Move_Files.ps1 将使用 Oracle APEX (web) 前端和 windows 命令行调用。因此,powershell 脚本作为“系统”运行,用户是“匿名”,不是有效的凭据。

到目前为止,我拥有的是一个名为“RUN.ps1”的 powershell 脚本,它应该使用特定的凭据(具有必要的写入权限)调用“Move_files.ps1”脚本。以下内容来自here

$ScriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$User = "domain\username"
$secpass = ConvertTo-secureString "password" -asPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($User,$secpass)
#Call script which Moves CSV to share
start-process powershell.exe -ArgumentList "$ScriptPath\Move_files.ps1" -Credential $cred     

从 PS 控制台成功调用上述代码 (RUN.ps1) 并运行 Move_files.ps1,但从 APEX 执行 CMD 命令时,RUN.ps1 运行但无法启动 Move_files.ps1。

我会记录所有打开的 PS1 文件,以便查看文件何时打开。 Start-transcript 没有提供任何可用的输出。非常感谢任何进一步的故障排除步骤或输入。

感谢您抽出宝贵时间提供帮助!


更新 1. 由于 PS1 脚本是从命令提示符启动的,因此 Transcript Start 没有输出任何结果。日志文件实际上必须从 APEX 和命令提示符生成(详细信息在输出下方):

Transcript started, output file is c:\Powershell\transcript0.txt
Start-Process : This command cannot be executed due to the error: Access is denied.
At C:\PowerShell\RUN.ps1:22 char:15 + start-process <<<<  powershell.exe -Credential $cred -file "& $ScriptPath\Move_files.ps1" + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand

我想这个“访问错误”是由于从命令提示符调用 powershell 造成的,因为使用的凭据具有对该文件夹的管理员访问权限。我猜下一步是使用该行获取本地环境变量

Get-ChildItem Env:  

重复这些步骤的任何人的快速操作方法:
调用 Powershell 脚本的 APEX 代码

BEGIN    SYS.DBMS_SCHEDULER.CREATE_JOB(         
job_name => 'PS_scripts' ,        
job_type => 'EXECUTABLE',        
job_action => 'C:\WINDOWS\system32\cmd.exe',                     
job_class => 'DEFAULT_JOB_CLASS',        
comments => 'Job to test call out to batch script on Windows',        
auto_drop => FALSE,        
number_of_arguments => 2,        
enabled => FALSE);     
--SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( --this function is commented out      
--job_name => 'PS_scripts' ,                 --reason is /q turns echo off
--argument_position => 1,                    --& we need eccho to get the log!
--argument_value => '/q');     
SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(         
job_name => 'PS_scripts' , 
argument_position => 1, argument_value => '/c');     
SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(         
job_name => 'PS_scripts' , 
argument_position => 2, 
argument_value => 'powershell "& C:\PowerShell\RUN.ps1" > "C:\Powershell\log.txt"'); --pipe the output here     
SYS.DBMS_SCHEDULER.ENABLE( 'PS_scripts' ); 
END;

【问题讨论】:

  • 你能发布成绩单吗?还将错误操作设置为停止以使非终止错误可见
  • 感谢 Paul,我现在不在办公桌前,但我一回来就会这样做。
  • 感谢@Paul 的洞察力,我花了更长的时间才承认让日志记录工作,但我认为我已经走上了正轨。我在上面记录了我的步骤。没有真正的进展,但至少我有日志记录!
  • 我用谷歌搜索了一下,似乎您无法使用系统帐户运行启动进程,在另一个线程中有人建议尝试 psexec,也许这会工作
  • 您可以尝试使用脚本来启动已提供凭据的已保存计划任务,但我不确定这是否可行。这是使用服务帐户而不是依赖SYSTEMNETWORK SERVICE 的主要原因之一。

标签: powershell command-line oracle-apex credentials


【解决方案1】:

我遇到了一个解决问题的函数。

Powershell 后台智能传输服务 (BITS) 有一个 -Credential 字段,因此可以使用来自 SYSTEM 以外的帐户的凭据传输文件。

我遇到了解决方案here

我的 Move_Files.ps1 代码现在如下所示:

$ScriptPath = split-path -parent $MyInvocation.MyCommand.Definition

Function Get-PSCredential($User,$Password)
{
$SecPass = convertto-securestring -asplaintext -string $Password -force
$Creds = new-object System.Management.Automation.PSCredential -argumentlist $User,$SecPass
Return $Creds
}

Import-Module BitsTransfer
$Destination = "\\domain.lan\shared\New_Location"
$credential = Get-PSCredential -User username -Password password

Get-ChildItem -Path "$ScriptPath\Old_Location\*.csv"  | Foreach-Object  {Start-BitsTransfer -source $_.fullname -destination $Destination -credential $credential}

Move_Files.ps1 现在可以轻松地从 RUN.ps1 调用:

start-process Powershell.exe -noprofile -executionpolicy Bypass -file C:\Move_files.ps1 

【讨论】:

    【解决方案2】:

    通过映射网络驱动器和预缓存凭据的更短的解决方案。

    找到here

    我的工作代码 (Move_files.ps1)

    $ScriptPath = split-path -parent $MyInvocation.MyCommand.Definition
    
    $Destination = ""\\domain.lan\shared\New_Location"
    $username = "username"
    $password = "password"
    
    net use $Destination $password /USER:$username
    
    Get-ChildItem -Path "$ScriptPath\Old_Location\*.csv"  | Foreach-Object  { copy-item -Path $_.fullname -Destination $Destination }
    
    #delete the share 
    net use $Destination /delete 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 2014-12-18
      • 1970-01-01
      • 2020-11-24
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多