见标题.
我在脚本的头部指定了所需的参数:
param ($G_ARCHIVE = $(throw "Need file to upload!"),
$G_LOGFILE = $(throw "Need logfile!"))
Run Code Online (Sandbox Code Playgroud)
当我想用Powershell ISE调试脚本时:我该如何填写这些参数?
转换大小超过2MB的JSON字符串时,我遇到使用PowerShell v3的问题.PowerShell使用的JSON序列化程序的默认限制设置为2MB,这解释了错误.
然而,当我在较小的集合上使用ConvertFrom-Json反序列化对象时(我得到了具有越来越大的内部集合的各种数据对象,但它们是相同的对象),它返回了非常好的对象,其中包含我可以轻松访问的所有属性.
为了克服序列化程序的限制,我尝试手动反序列化数据:
$jsser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$jsser.MaxJsonLength = $jsser.MaxJsonLength * 10
$jsser.RecursionLimit = 99
$outObject = $jsser.DeserializeObject($json)
Run Code Online (Sandbox Code Playgroud)
对象看起来不同似乎内部集合没有反序列化,当我尝试执行属性时,它们返回空结果.
我的问题:
ConvertFrom-Json
在序列化之前,假设是做一些额外的魔术或以某种方式为对象创建模板.知道如何复制它吗?
我得到的对象总是一个PSCustomObject
; 如果我得到我想要设置的对象,ConvertFrom-Json
那么无论如何在JsonSerializer中将它用作对象类型?
我遇到了像这样声明的变量(或参数):
${var_name} = "Hello world!"
Run Code Online (Sandbox Code Playgroud)
据我所知,这与以下内容没有什么不同:
$var_name = "Hello world!"
Run Code Online (Sandbox Code Playgroud)
我想知道{}
第一个例子中的括号是否有意义.他们是否改变了变量的行为?
-WhatIf
TL;DR:为什么从脚本调用时模块函数不会隐式继承?
据我了解,cmdlet 和函数将继承诸如-WhatIf
调用脚本之类的开关,但是我看到的行为表明情况并非总是如此。我已确认如何在调用其他 Cmdlet 的 Cmdlet 中支持 PowerShell 的 -WhatIf 和 -Confirm 参数?对我来说工作正常,但是当我的脚本调用模块中定义的函数时,问题似乎发生了。
就我而言,我有一个脚本,其中包含本地定义的函数(即在 PS1 中)文件。该脚本导入一个脚本模块。当我使用开关运行主脚本时-WhatIf
,本地函数继承-WhatIf
状态,但模块函数不会表现出“WhatIf”行为,这可能是灾难性的。
如果我显式调用开关集Show-WhatIfOutput
,-WhatIf
它会按预期工作。
如果我将Call-ShowWhatIf
函数从脚本移动到模块并使用它,Call-ShowWhatIf -WhatIf
它就可以正常工作。也就是说,Show-WhatIfOutput
确实已-WhatIf
隐式设置,但这不是我可以在实际情况中使用的解决方案。
更简单的是,如果我启用SupportsShouldProcess
在主脚本上启用,则会出现相同的模式:本地函数将继承开关;但是,模块功能不会。
-WhatIf
为什么从脚本调用模块函数时不继承?
测试-WhatIf.psm1
function Show-WhatIfOutput {
[CmdletBinding(SupportsShouldProcess)]
param(
)
Write-Host $MyInvocation.Line.Trim()
if($PSCmdlet.ShouldProcess("My host","Display WhatIf text")){
Write-Warning "This is not WhatIf text!"
}
Write-Host ("-"*40)
}
Run Code Online (Sandbox Code Playgroud)
测试-WhatIf.ps1
Import-Module C:\Test-WhatIf.psm1 -Force
function Call-ShowWhatIf {
[CmdletBinding(SupportsShouldProcess)]
param(
)
Write-Host …
Run Code Online (Sandbox Code Playgroud) 我正在尝试向powershell中的表单添加进度条.我不想使用PowerShell的Write-Progress cmdlet(因为当我从命令行运行脚本时,它显示了一个基于文本的进度条,我总是想要一个基于表单/图形的栏).
我试过这个似乎工作(在网上找到):
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
$form_main = New-Object System.Windows.Forms.Form
$progressBar1 = New-Object System.Windows.Forms.ProgressBar
$timer1 = New-Object System.Windows.Forms.Timer
$timer1_OnTick = {
$progressBar1.PerformStep()
}
$form_main.Text = 'ProgressBar demo'
$progressBar1.DataBindings.DefaultDataSourceUpdateMode = 0
$progressBar1.Step = 1
$progressBar1.Name = 'progressBar1'
$form_main.Controls.Add($progressBar1)
$timer1.Interval = 100
$timer1.add_tick($timer1_OnTick)
$timer1.Start()
$form_main.ShowDialog()| Out-Null
Run Code Online (Sandbox Code Playgroud)
但是,我不希望事件更新进度条(如上例中的$ timer1_OnTic)我想通过在整个脚本中调用来自行更新它,例如:
$progressBar1.PerformStep()
Run Code Online (Sandbox Code Playgroud)
要么
$progressBar1.Value = 10
Run Code Online (Sandbox Code Playgroud)
因此,似乎我需要某种后台工作程序,只要我调用PerformStep()或更改progressBar的值,就会更新进度条
调用ShowDialog会停止脚本内的所有处理,直到表单关闭.
我喜欢改变PowerShell ISE的默认颜色方案,特别是使脚本窗格"反转",即在深色背景上的浅色文本.评论的颜色为PaleGreen:
[PS]> ($psise.Options.TokenColors) | ?{$_.Key -eq "Comment"} | FT -AutoSize
Key Value
--- -----
Comment #FF98FB98
Run Code Online (Sandbox Code Playgroud)
我也喜欢使用#region ... #endregion
注释来允许我折叠代码块.
当它们没有折叠时,#region
和#endregion
评论显示为绿色,就像任何其他评论一样,但是一旦我将它们折叠它们就变成黑色,使它们在黑暗的背景上几乎看不见.其他部分(功能等)在折叠时不会出现颜色.
有谁知道是否可以设置折叠 #region
和#endregion
评论的颜色?
我已经(继承)了一个PowerShell脚本,该脚本通过使用Start-Job
cmdlet和-FilePath
参数调用其他PowerShell脚本来调用它们。例如,我有一个不执行任何操作的脚本:
Start-Sleep -Seconds 86400
Run Code Online (Sandbox Code Playgroud)
我可以通过工作来调用:
PS> Start-Job -Name "Test Job" -FilePath ".\Wait-AllDay.ps1"
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
2 Test Job BackgroundJob Running True localhost Start-Sleep...
PS> Get-Job -Id 2
State : Running
HasMoreData : True
StatusMessage :
Location : localhost
Command : Start-Sleep -Seconds (60*60*24)
JobStateInfo : Running
Finished : System.Threading.ManualResetEvent
InstanceId : 0c0e2c32-cbc5-4d70-b7cb-28771626cf20
Id : 2
Name : Test Job
ChildJobs : {Job3}
PSBeginTime : 25/01/2016 …
Run Code Online (Sandbox Code Playgroud) 我通常SupportsShouldProcess
在 PowerShell 函数中使用$PSCmdlet.ShouldProcess()
,以便我可以对脚本将要执行的操作进行健全性检查。一般来说,我仅围绕将更改环境的操作来实现此操作,例如Add-、New-、Set- cmdlet 等。在某些情况下,我还想在使用开关运行脚本时绕过Get--WhatIf
cmdlet 。例如:
我有一个脚本,可以在对每个文件执行某些操作Get-FileHash
之前对文件夹中的所有文件进行指纹识别。在此示例中,有 10k+ 个文件,平均大小为 100MB 或更大,当我使用. 我无法将整个操作包装为一个块。-WhatIf
$PSCmdlet.ShouldProcess("All Files","Get-FileHash")
在循环中运行每个项目的效果$PSCmdlet.ShouldProcess()
是,我将数千行“What if:”文本转储回控制台。
问题:有没有办法使用$PSCmdlet.ShouldProcess()
它而不写入控制台?如果没有,人们可以使用什么解决方法?
示例代码
虽然我认为这个问题只是在抽象意义上起作用,但这是一个非常实用的论坛,所以这里是我上面提到的任务的一个简单示例:
$Files = Get-ChildItem -Path <ReallyBigFolder>
foreach($File in $Files){
$Action = Get-MyAction -Filename -$File.Fullname
# Take hash of file
$Hash = Get-FileHash -Path -$File.Fullname
# Keep audit happy
Write-Audit -Action $Action -Hash $Hash
switch($Action){
"Retain" {
# do nothing
break …
Run Code Online (Sandbox Code Playgroud) 我一直在比较在Powershell中快速读取相对较大的文本文档的各种方法。这些文件的大小范围为 50kb - 200mb。我需要快速解析它们以获取特定的行和/或特定的字符串。
读取文件的三个常用工具(我知道,并且没有构建我自己的 C# 库)是:System.IO.StreamReader、System.IO.File 和 Powershell Cmdlet Get-Content。
所以我写了一个快速的小比较脚本:
$file = Get-Childitem -path "MyLogFile.txt" #This is a 100mb txt file
$t1 = Measure-Command{
$reader = New-Object System.IO.StreamReader($file)
$content = $reader.ReadToEnd()
$reader.Close()
}
Write-host "StreamReader time: " + $t1
$t2 = Measure-Command{
Get-Content $file
}
Write-host "Get-Content time: " + $t2
$t3 = Measure-Command {
$reader = [System.IO.File]::OpenText($file)
$content = $reader.ReadToEnd()
$reader.Close()
}
Write-Host "System.IO.File reader time: " + $t3
Run Code Online (Sandbox Code Playgroud)
它产生(当然略有变化)以下输出:
StreamReader time: + 00:00:00.5493247
Get-Content time: + …
Run Code Online (Sandbox Code Playgroud)