当计算机启动时,我该如何运行PowerShell脚本?

88
我有一个监视图像文件夹的 PowerShell 脚本。我需要找到一种方法,在计算机启动后自动运行此脚本。
我已尝试以下方法,但均未成功:
1. 使用 msconfig 并将 PowerShell 脚本添加到启动项中,但在该列表中找不到 PowerShell 脚本。 2. 创建快捷方式并将其拖到启动文件夹。没有成功。
%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -File "C:\Doc\Files\FileMonitor.ps1"
或者
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Doc\Files\FileMonitor.ps1"

这是我的PowerShell脚本:

$folder = "C:\\Doc\\Files"
$dest = "C:\\Doc\\Files\\images"
$filter = "*.jpg"

$fsw = new-object System.IO.FileSystemWatcher $folder, $filter -Property @{
    IncludeSubDirectories=$false
    NotifyFilter = [System.IO.NotifyFilters]'FileName, LastWrite'
}

$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {

    Start-Sleep -s 10
    Move-Item -Path C:\Doc\Files\*.jpg C:\Doc\Files\images
}
  • 我还尝试使用taskschd.msc添加基本任务,但它仍然无法运行。

    这是我发现的情况,也许可以帮助调试:

    如果我在 PowerShell 窗口中打开并运行脚本,则可以正常工作。但如果我在命令提示符中运行,

  • powershell.exe -File "C:\Doc\Files\FileMonitor.ps1"
    

    无法运行。我不确定是权限问题还是其他问题。

    顺便说一下,我已经安装了 PowerShell 3.0,如果我键入 $host.version,它会显示 3。

    但是我的 powershell.exe 似乎仍然是 v1.0。

    %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
    

    v1.0 powershell.exe 是 v3。微软公司在将文件移动到新版本的新文件夹方面有些懒惰。例如,在 x64 上的 System32 是 x64,而 syswow64 是 32 位。 - Knuckle-Dragger
    你真的需要在前几行中使用双斜杠“c:\doc\files”吗?为什么不使用“c:\doc\files”呢? - Knuckle-Dragger
    你是否在Superuser上重复发布了? - Knuckle-Dragger
    我发现这个,也许能帮助其他人https://jd-bots.com/2021/05/15/how-to-run-powershell-script-on-windows-startup/ - X0-user-0X
    17个回答

    87

    我终于成功让我的PowerShell脚本在每次启动时自动运行。您需要创建两个文件:第一个是Powershell脚本(例如script.ps1),第二个是包含在命令提示符上运行的命令的 .cmd文件(例如startup.cmd)。

    当计算机启动时,需要执行第二个文件,并且简单地将 .ps1复制并粘贴到启动文件夹中是不会起作用的,因为那样并没有真正执行脚本-它只是用记事本打开了该文件。你需要执行 .cmd文件,它本身将使用PowerShell执行 .ps1文件。好了,足够啰嗦了,现在我们进入步骤:

    1. 创建您的 .ps1脚本并将其放在文件夹中。出于简单起见,我将其放在桌面上。路径看起来会像这样:

    %USERPROFILE%\Desktop\script.ps1

    1. 创建一个 .cmd文件并将其放在以下位置:

    %AppData%\Microsoft\Windows\Start Menu\Programs\Startup\startup.cmd

    这样做将在每次启动时执行 cmd 文件。如果需要帮助,请这是创建 .cmd文件的链接

    1. 用文本编辑器打开 .cmd文件并输入以下行:
    PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> "%TEMP%\StartupLog.txt" 2>&1
    PowerShell %USERPROFILE%\Desktop\script.ps1 >> "%TEMP%\StartupLog.txt" 2>&1
    

    这将完成两件事:

    1. 将您的PowerShell执行策略设置为无限制。这是运行脚本所需的,否则PowerShell将不会运行它。
    2. 使用PowerShell来执行在指定路径中找到的.ps1脚本。

    此代码专门针对PowerShell v1.0。如果您正在运行PowerShell v2.0,则可能会有些不同。无论如何,请查看此源以获取.cmd代码。

    1. 保存.cmd文件

    现在,您已经在各自的路径中拥有了.p s1和.cmd文件,并为每个脚本编写了脚本,您已经准备好了。


    11
    对我来说,它只在管理员用户登录时执行命令,而不是在每次系统启动时都执行,这与我的预期不同。 - ThiagoAlves
    作为管理员,在开始菜单中找到“启动”文件夹,右键单击它,然后单击“打开所有用户”。将您的脚本.cmd放在那里,它应该在任何用户登录时运行。这与在启动时运行(即在任何用户登录之前)不同,但很可能足够接近。 - jpaugh
    5
    如果登录的用户不是管理员,请将当前用户(不要替换为你的用户名)添加到第一个命令的结尾,如下所示:PowerShell -Command "Set-ExecutionPolicy Unrestricted CurrentUser" - Dan Ross
    对于第二步,只需按下Windows + R,然后输入:%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\,即可进入该文件夹。 - Hobbamok
    6
    有一个回答获得了很多赞,该回答描述的是当用户登录时运行某些操作,而不是在登录提示符(即“电脑启动时”)处运行操作。请注意,这里的重点是登录时而非登录提示符处。 - user66001
    显示剩余2条评论

    22
    我所做的是创建一个快捷方式,将其放置在shell:startup中。
    快捷方式具有以下内容:
    目标:C:\ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe -Command“C:\ scripts \ script.ps1” (用所需的脚本替换scripts \ scripts.ps1)
    启动位置:C:\ scripts (用包含脚本的文件夹替换scripts)

    遇到了一些问题,后来意识到我没有指定“开始位置”。按照您的回答进行设置后,它就起作用了。谢谢。 - Leo Ufimtsev
    这会弹出一个 PowerShell 窗口,正是我想要的。 - Leo Ufimtsev
    1
    “shell:startup”和“Start In: C:\scripts”分别是什么,它们在哪里?谢谢。 - Timothy L.J. Stewart
    3
    当你查看快捷方式的属性时,有一个“起始于”选项,你可以在那里添加脚本所在的文件夹。通过打开运行命令(Win+R),输入shell:startup可以打开Shell的启动目录。 - haboutnnah
    这个只有在我手动登录时才运行,而不是在虚拟机启动时 :-( - stevec
    遗憾的是,这根本就不起作用。如果我手动双击快捷方式,则会要求管理员授权并正常运行。然而,退出并重新登录后脚本不会运行。Windows 10 出了问题... - Jonathan Benn

    22

    您可以将其设置为计划任务,并将任务触发器设置为“在启动时”。


    请确保将 Set-ExecutionPolicy Elevated 设置为 RemoteSigned 或您选择的首选项。然后,您的方法 " %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Doc\Files\FileMonitor.ps1" " 应该可以正常工作。 - Bill
    仍然无法工作,这正确吗?powershell.exe -ExecutionPolicy unrestricted -File "C:\Doc\Files\FileMonitor.ps1" - qinking126
    2
    我相信你还需要指定-NoExit,这样它才会继续运行,否则它只会注册事件然后退出,带着事件注册一起退出。 - mjolinor
    请确保你勾选了允许在没有用户登录时运行的选项框。 - Robin Salih
    3
    这是正确的答案,但我在实现过程中遇到了一些问题,详见 --> https://dev59.com/zWIj5IYBdhLWcg3wJCB-#64096259 - FreeSoftwareServers

    12
    您可以创建一个定时任务,在启动时自动运行,即使用户未登录:
    schtasks /create /tn "FileMonitor" /sc onstart /delay 0000:30 /rl highest /ru system /tr "powershell.exe -file C:\Doc\Files\FileMonitor.ps1"
    

    以管理员身份在 PowerShell 中运行此命令一次,它将为您创建一个计划任务。您可以像这样列出任务:

    schtasks /Query /TN "FileMonitor" /V /FO List
    

    或者删除它

    schtasks /Delete /TN "FileMonitor"
    

    计划任务命令的文档可以在这里找到:https://learn.microsoft.com/zh-cn/windows/desktop/taskschd/schtasks - hirschnase

    11

    这实际上只是对@mjolinor简单答案 [使用任务计划程序]的扩展。

    我知道“任务计划程序”是正确的方式,但需要付出一些努力才能按照自己的意愿运行它,因此我想发布我的发现供他人参考。

    问题包括:

    • 将输出重定向到日志
    • 隐藏PowerShell窗口

    注意:您必须有运行脚本的权限,请查看ExecutionPolicy

    然后,在任务计划程序中,最重要/棘手的部分是Action

    它应该是启动程序

    程序/脚本:

    powershell
    

    添加参数(可选):

    -windowstyle hidden -command full\path\script.ps1 >> "%TEMP%\StartupLog.txt" 2>&1

    注意:

    如果你在互联网上看到 -File,它会正常工作,但是请注意,在 -File 后面不能有其他内容,只能加文件路径,即:重定向被视为文件路径的一部分,并且会导致失败。你必须使用 -command 结合重定向,但可以在其前面添加其他命令/参数,例如 -windowstyle hidden 来隐藏 PowerShell 窗口。

    我还需要把我的脚本中的所有 Write-Host 改为 Write-Output


    1
    我的错误是点击了“更改用户或组…”并将其设置为admin,虽然成功了,但似乎从未真正启动程序。尝试使用默认用户时,它确实起作用了! - undefined

    7
    尝试这样做:在启动文件夹中创建一个快捷方式,然后输入以下内容。
    PowerShell "& 'PathToFile\script.ps1'"
    

    这是最简单的方法。


    2
    我必须删除'&'后面的'.',这样才能使它正常工作。 - generic-user
    这对我来说完美地运行了(在去掉点号之后)。 - alib0ng0

    4

    先决条件:

    1. 使用“以管理员身份运行”选项启动PowerShell。

    2. 使用以下命令启用运行未签名的脚本:

    set-executionpolicy remotesigned
    

    3. 准备你的PowerShell脚本,并知道它的路径:

    $path = "C:\Users\myname\myscript.ps1"
    

    步骤:

    1. 设置触发器,详见New-JobTrigger (PSScheduledJob) - PowerShell | Microsoft Docs

    $trigger = New-JobTrigger -AtStartup -RandomDelay 00:00:30
    

    2. 注册一个定期任务,另请参阅Register-ScheduledJob (PSScheduledJob) - PowerShell | Microsoft Docs

    Register-ScheduledJob -Trigger $trigger -FilePath $path -Name MyScheduledJob
    

    你可以使用Get-ScheduledJob -Name MyScheduledJob来检查它。

    3. 重新启动Windows(restart /r),并使用以下命令检查结果:

    Get-Job -name MyScheduledJob
    

    另请参阅Get-Job (Microsoft.PowerShell.Core) - PowerShell | Microsoft Docs

    参考文献:

    1. 如何启用 PowerShell 脚本的执行权限?- Super User
    2. 使用 PowerShell 创建在启动时运行的作业 | scripting Blog

    3

    将ps1复制到此文件夹中,如果需要则创建。它会在每次启动时运行(在用户登录之前)。

    C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup
    

    如果系统版本支持,也可以通过GPEDIT.msc来完成(较低版本的操作系统可能不支持)。

    3
    我已将我的ps1文件复制到上述文件夹中,但它对我来说不起作用……你有任何想法,可能是什么原因? - Suresh Kota

    2

    如果你希望PowerShell自动运行/在后台/非交互式运行,请务必指定参数-ExecutionPolicy Bypass给PowerShell.exe。

    PowerShell.exe -ExecutionPolicy Bypass

    将这个参数加入命令中可以确保PowerShell能够正确运行,不会出现错误提示。


    1

    我发现的一件事是,如果你在 PowerShell 脚本中使用 Write-Host,并且也使用任务计划程序(如上面的帖子所示),则无法从命令行获取所有输出。

    powershell.exe -command C:\scripts\script.ps1 >> "C:\scripts\logfile.log"
    

    在我的情况下,我只能看到从PowerShell脚本成功运行的命令的输出。
    目前我的结论是,PowerShell使用Out-File将输出输出到另一个命令或在这种情况下输出到日志文件。
    因此,如果您使用*>而不是>>,您将获得CLI的所有输出,并且您可以继续在脚本中使用Write-Host。
    powershell.exe -command C:\scripts\script.ps1 *> "C:\scripts\logfile.log"
    

    https://lazyadmin.nl/powershell/output-to-file/

    您还可以在后台运行脚本,而不管用户是否登录。

    在任务计划程序中的任务中,设置“无论用户是否登录都要运行”,然后在密码提示中输入您的主机名\用户名,然后输入密码(在我这个例子中是具有管理员权限的帐户)。

    我使用Set-ExecutionPolicy RemoteSigned -Scope CurrentUser来解决脚本执行问题。虽然我更希望它能够基于每个进程运行,但这是另一个时间的问题。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接