【问题标题】:run PowerShell script from CMD (tricky one)从 CMD 运行 PowerShell 脚本(棘手的一个)
【发布时间】:2019-12-19 09:34:03
【问题描述】:

我知道这听起来像是以前的问题(部分是真的)。 然而,我在这里有一个有趣的转折。

需要的流量:
从 CMD 运行 Powershell 脚本。 看起来微不足道,实际上可以通过传递参数等...
但是...
我的 powershell 脚本中有一个 Start-Job,因为我希望它异步运行。

#######################################################################

   #$DropLocation = "SOME UNC PATH"
   #$buildid = "SOME VERSION"
param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 


Start-Job -Name Upload `
-ScriptBlock {

param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 
Write-Output "asd"
$buildpath = $DropLocation+"\"+$buildid
$logs = gci $buildpath"\logs" -Name "ActivityLog.AgentScope*.xml"

#Start-Sleep -Seconds 300

if ($logs.PSPath -gt 0)
    { 
        $destination = $env:TEMP+"\Config\"
        Copy-Item $logs.PSPath "$destination $buildid.xml"
    }
} `
-ArgumentList $DropLocation,$buildid

#######################################################################

我正在使用 Param 从外部获取,然后再次在 Start-Job 中,以便 Async 作业获取其参数

此脚本保存为 SCRIPTNAME.ps1,我正在尝试从 CMD 运行它。

来自 cmd(以管理员身份运行)

powershell "& "C:\temp\SCRIPTNAME.ps1" "SOME UNC PATH" "SOME VERSION""

powershell -file "C:\temp\SCRIPTNAME.ps1" "SOME UNC PATH" "SOME VERSION"

什么都没有发生。
然而,从 PowerShell ISE 一切都运行良好

我们非常感谢您的帮助!

【问题讨论】:

  • 你试过cd C:\location of ps.1并运行.\thefile.ps1吗?
  • 您必须将第一个命令中嵌入的" 转义为\"。第二个命令看起来正确(并且是更好的选择)。当你说什么都没有发生时,你能更具体一点吗?没有错误信息?脚本是否被调用?
  • 嘿,我希望将文件复制到特定位置,但这并没有发生。而当从 Powershell ISE 运行与 PS1 脚本相同的情节时,它工作正常......我觉得在 CMD 调用期间我可能会遗漏一些东西
  • 不幸的是,这给了我这个错误:找不到与参数名称“Argumentlist”匹配的参数
  • 嗯!第一次运行,我看到了结果!作为构建调用的一部分,将在测试环境中尝试它^_^

标签: windows powershell cmd command-line


【解决方案1】:

powershell -noexit ". C:\temp\SCRIPTNAME.ps1"

点源它,这将更改源函数的范围,以使您的工作在当前运行的脚本范围内工作,同时还允许您运行多个线程。

【讨论】:

  • 将在 7 小时内测试
  • “.C:\ ...”中的点没有做任何事情。它的 -noexit 参数使它发生。无论哪种方式,您都为我们提供了解决方案!
  • 顺便说一句,这适用于 Windows 10,但不适用于 Win Server 2016 .....
【解决方案2】:

根据提供的脚本,我对您的问题的看法是,您的脚本在作业完成之前退出。

--

这两种行为并列

ISE / VSCode

  • 脚本启动
  • Start-Job 被调用
  • 脚本完成
  • 作业完成

CMD

  • 脚本通过cmd启动
  • Start-Job 被调用
  • 脚本完成
  • Powershell 会话被终止(并且作业执行被终止)
  • 工作永远不会完成

为防止会话在作业完成之前被终止,请在脚本末尾添加以下行 Receive-Job -Name 'upload' -Wait

这是经过修改的新脚本。

#######################################################################

   #$DropLocation = "SOME UNC PATH"
   #$buildid = "SOME VERSION"
param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 


Start-Job -Name Upload `
-ScriptBlock {

param (
        [parameter(Mandatory = $true)][string]$DropLocation,
        [parameter(Mandatory = $true)][string]$buildid
       ) 
Write-Output "asd"
$buildpath = $DropLocation+"\"+$buildid
$logs = gci $buildpath"\logs" -Name "ActivityLog.AgentScope*.xml"

#Start-Sleep -Seconds 300

if ($logs.PSPath -gt 0)
    { 
        $destination = $env:TEMP+"\Config\"
        Copy-Item $logs.PSPath "$destination $buildid.xml"
    }
} `
-ArgumentList $DropLocation,$buildid

# Prevent the session to be killed before the job return.
Receive-Job -Name 'upload' -Wait 
#######################################################################

【讨论】:

  • 嘿,谢谢你的建议,我故意运行 Start-Job 因为我需要它是异步的(我不想等待它)。
【解决方案3】:

在不知道环境的配置文件/策略配置的情况下,我是否建议在下面的示例中使用配置文件/策略修饰符进行调用?有时它们可​​以对从批处理执行 powershell 产生重大影响

您是否尝试过在 Batch 中编写生成和执行 powershell 脚本

每当我需要 powershell 来执行 cmd 无法执行的操作时,我都会将脚本编写为可以从批处理文件中调用的函数。

这是我的方法的一个示例:

:createshortcut
(
ECHO # Create a Shortcut with Windows PowerShell
ECHO $SourceFileLocation = "%ShortcutTargetPATH%"
ECHO $ShortcutLocation = "%userprofile%\Desktop\%shortcutname%.Ink"
ECHO #New-Object : Creates an instance of a Microsoft .NET Framework or COM object.
ECHO #-ComObject WScript.Shell: This creates an instance of the COM object that             
represents the WScript.Shell for invoke CreateShortCut
ECHO $WScriptShell = New-Object -ComObject WScript.Shell
ECHO $Shortcut = $WScriptShell.CreateShortcut($ShortcutLocation^)
ECHO $Shortcut.TargetPath = $SourceFileLocation
ECHO $Shortcut.IconLocation = "%IconPATH%\%IconNameEXT%"
ECHO #Save the Shortcut to the TargetPath
ECHO $Shortcut.Save(^)
) >%AppDataPATH%\%PowerShellnameEXT%

TIMEOUT 1 >nul

Powershell.exe -NoProfile -ExecutionPolicy Bypass -File %AppDataPATH%\%PowerShellnameEXT%

TIMEOUT 1 >nul

DEL /Q "%AppDataPATH%\%PowerShellnameEXT%"

GOTO :EOF

设置脚本执行所需的值,然后调用函数。使用这种方法时要记住的关键是在编写 .ps1 文件时转义适当的字符

【讨论】:

  • 嘿,这实际上是一个有趣的方法,但问题是,在使用 Start-Job 时,它似乎没有做任何事情,即使脚本本身运行良好(没有将其删除为你提到过)。请尝试模拟问题描述中提出的我的脚本。
  • #Start-Sleep -Seconds 300 是否有原因被注释掉了?您是否尝试过 powershell.exe 而不是问题中显示的 powershell?
  • 在实际运行期间将使用注释的 Start-Sleep,已过期,因此脚本不会保持 5 分钟。我尝试过 powershell.exe 和 powershell...
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 2016-07-13
  • 1970-01-01
  • 2018-06-25
  • 2015-10-19
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多