我有一个主脚本有几个选项.当您在菜单中选择1时,将执行操作1,然后您将返回菜单.这工作正常,但我希望能够选择例如8,它在新的PowerShell窗口中启动Permissions脚本的代码块.我想将所有代码放在一个脚本中,而不是调用另一个脚本.
我知道这可以通过几个威胁中的"Start-Process powershell"来完成.这会打开一个新的PowerShell窗口,但不会正确执行Permissions脚本的代码块.任何帮助,将不胜感激.
主脚本:
<# Author: Me #>
# Variables
$User = [Environment]::UserName
$OutputPath = "C:\Users\$User\Downloads\"
# Functions
Function Manager ($u) {
$m = Get-ADObject -Identity $u.managedBy -Properties displayName,cn
if($m.ObjectClass -eq "user") { $m.displayName } Else{ $m.cn } }
# Hit play
do {
[int]$userMenuChoice = 0
cls
while ( $userMenuChoice -lt 1 -or $userMenuChoice -gt 7) {
Write-Host "PowerShell for dummies"
Write-Host "__________________________________________________"
Write-Host "1. Groups created in the last 3 weeks"
Write-Host …Run Code Online (Sandbox Code Playgroud) 考虑 powershell 命令:
cmd.exe "/c start notepad.exe"
Run Code Online (Sandbox Code Playgroud)
使用 powershell.exe(控制台),此命令在启动 cmd/notepad 进程后立即完成,不会等待 notepad/cmd 退出。如果我希望它等待完成,我必须将输出通过管道传输到 Out-Null。
使用 powershell ISE,此命令会阻止执行,直到关闭记事本/cmd。
此外,如果我使用 System.Diagnostics.Process 在 powershell.exe 中运行的脚本中创建一个新进程(powershell.exe)并重定向标准输出,则脚本现在会阻止执行,直到关闭记事本/cmd。如果我不重定向输出,它不会阻止执行。
但是,如果我使用 C# 创建具有相同设置/启动信息的新进程,并使用重定向输出运行相同的脚本,则不会阻止执行。
我在这里不知所措。显然,它与执行和输出的设置有关,可能与“cmd.exe”有关。我希望有人能够理解这些情况下幕后发生的根本不同的事情。我知道 ISE 和 cmd.exe 不受完全支持,但我不知道为什么其他 3 个不一致。
为什么脚本不以相同的行为运行(尤其是 powershell 控制台脚本)以及如何让它们以相同的行为运行?
编辑:
经过一些故障排除后,我能够让所有 powershell.exe 版本以相同的方式运行(ISE 对我来说并不重要)。阻止执行的奇怪问题cmd.exe "/c start notepad.exe"是当在 powershell 中创建一个新进程以使用 .exe 运行 powershell.exe 时System.Diagnostics.Process。System.Diagnostics.Process如果输出被重定向(我首先使用的原因是,Start-Process除了重定向到文件之外,不支持重定向),然后调用WaitForExit()进程对象会导致发生阻塞。
只需替换WaitForExit()为Wait-Process(和进程 ID)即可导致在新 powershell.exe 中运行的 powershell 脚本按预期执行并在运行命令后退出。希望这些信息与 @mklement0 答案相结合对于其他有类似问题的人来说是足够的。
我有一些像这样的视频文件:
VideoName_s01e01.mp4季节和剧集是变量.我想在s??和之间添加一个下划线("_")e??.
我一直在使用powershell进行重命名,我有一个起点:
GCI $path -filter '*_s??e??*' -rec | Ren -new { $_.name -replace '_s[0-9][0-9]', '_s[0-9]_[0-9]_' } -passthru
Run Code Online (Sandbox Code Playgroud)
这实际上重命名了我的文件VideoName_s[0-9]_e[0-9].mp4.
基本上,我正在寻找s??e??我不知道如何在替换部分中使它们成为变量的字符.
我认为最好的方法是:
e??s??(我们称之为X)的位置.X-3._到中间的" ".今天,我在 Powershell 5.1 中使用制表符自动完成功能来输入变量名称,并注意到其中一个选项是 PSDrive 的名称。驱动器名称是docs,我想要扩展的驱动器名称是$document_name。当我输入 时$do<tab>,shell 确实扩展了我输入的内容$document_name,但由于某种原因,我第二次输入<tab>,此时扩展的文本更改为$docs:。
我进一步探索并发现我的每个 PSDrive 都存在这种类型的变量,或者至少选项卡扩展表明它确实存在。
\n\n更正式地说,对于每个 PSDrive PSD,选项卡扩展都认为这$PSD:是有效的事情。
我的问题很简单:这些到底是什么?以下是我迄今为止所做的一些观察:
\n\n$,因此它们看起来像 PS 变量。对于本次讨论的其余部分(以及上面前面的讨论),我将假设它们是变量并这样引用它们。Variable:像大多数变量一样列在 PSDrive 中。这样,它的行为就像$env“变量”,也没有在 中列出Variable:。我有一种感觉,如果我能找到有关 的文档$env,那么我也会理解这些对象。readme.txt包含文本“Hello, world!” 在名为 的 PSDrive 上code,则以下所有内容都可能与 Powershell 交互。获取文件的内容。
\n\n\xce\xbb ${code:\\readme.txt}\nHello, world!\nRun Code Online (Sandbox Code Playgroud)\n\n只是为了证明上面结果的类型是String:
我正在尝试执行Invoke-Sqlcmd命令(来自SqlServer 模块)以作为不同的 AD 用户运行查询。我知道有-Credential争论,但这似乎不起作用。
因此,我认为 usingStart-Job可能是一种选择,如下面的代码片段所示。
$username = 'dummy_domain\dummy_user'
$userpassword = 'dummy_pwd' | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential ($username, $password)
$job = Start-Job -ScriptBlock {Import-Module SqlServer; Invoke-Sqlcmd -query "exec sp_who" -ServerInstance 'dummy_mssql_server' -As DataSet} -Credential $credential
$data = Receive-Job -Job $job -Wait -AutoRemoveJob
Run Code Online (Sandbox Code Playgroud)
但是,在查看作业返回的变量类型时,这不是我所期望的。
> $data.GetType().FullName
System.Management.Automation.PSObject
> $data.Tables[0].GetType().FullName
System.Collections.ArrayList
Run Code Online (Sandbox Code Playgroud)
如果我ScriptBlock直接在 中运行代码,这些是 PS 返回的变量类型:
> $data.GetType().FullName
System.Data.DataSet
> $data.Tables[0].GetType().FullName
System.Data.DataTable
Run Code Online (Sandbox Code Playgroud)
我尝试将$data变量强制转换为[System.Data.DataSet],这导致了以下错误消息:
Cannot convert …Run Code Online (Sandbox Code Playgroud)