我刚刚了解了在我自己的Write-Verbose函数之上使用Write-Debug &Write-Debug的好处,您可以在下面找到它:
Function Write-Log
{
param($logType, $logString, $logFile, [switch]$newLine)
$time = get-date -Format "HH:mm:ss"
$date = get-date -Format "yyyy-MM-dd"
$line = "[${date}][${time}][$logType] ${logString}"
if ($logFile)
{
$retryDelay = 0.5;
$maxRetries = 10;
$retries = 0;
while($retries -lt $maxRetries)
{
try
{
$line | out-file -Encoding utf8 -Append $logFile
break;
}
catch
{
++$retries;
Sleep $retryDelay;
}
}
}
if ($logType -eq 'INFO')
{
write-host -ForegroundColor Green $line
}
elseif ($logType -eq 'WARN')
{
write-host -ForegroundColor Yellow $line
}
elseif ($logType -eq 'ERROR')
{
write-host -ForegroundColor Red $line
}
if ($newLine -eq $true)
{
write-host
}
}这有助于我尽可能少地将脚本输出弄得乱七八糟,并包括一个时间戳,在调试时非常方便。
问题
是否有一种方法来重载Write-Verbose,使其以下列方式运行?
PS > Write-Verbose -Message 'I am a verbose message!'
[2016-02-25][07:44:36] VERBOSE: I am a verbose message! 编辑
我发现了以下内容,不幸的是,它不符合$VerbosePreference变量的要求:
$VerbosePreference = "SilentlyContinue"
Function Private:Write-Verbose ($Message)
{
$time = get-date -Format "HH:mm:ss"
$date = get-date -Format "yyyy-MM-dd"
$line = "[${date}][${time}] "
Write-Host $line -NoNewline
&{Write-Verbose -Message $Message}
}
Write-Verbose -Message "Test"上面的内容只是输出日期和时间戳,而不需要消息。
发布于 2016-02-25 07:10:55
写-详细驻留在Microsoft.PowerShell.Utility中,因此这是不可能的;如果不操作和更改Powershell中的内置行为(这应该避免)。
您可以在脚本/会话范围内创建自己的“写-详细”函数;该函数将输出所需的结果(使用cmdletbinding());或者使用输出消息,如“详细的: 2016-02-25您的日志消息”(依赖于写-详细的默认行为)。
我推荐后者,除非您对主机有一些奇怪的输出要求。
如果继续创建自己的写-详细函数,则应该在params之前使用cmdletbinding();因为这样可以将默认参数/开关传递给函数(如-verbose / -information、-debug等)。有关binding绑定和参数绑定的详细信息,请参阅:
https://posh2scripting.wordpress.com/2013/06/05/what-is-cmdletbinding/
最后一件事;不建议在脚本中直接使用写主机,因为这会导致默认的流重定向(等等)。如果要将信息打印到流中,我强烈建议使用写-详细、写-调试、写-信息、写-输出cmdlet。
有关不使用写主机的更多信息,请参见:
http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/
http://powershell.com/cs/blogs/donjones/archive/2012/04/06/2012-scripting-games-commentary-stop-using-write-host.aspx
希望这能回答你的问题。
发布于 2016-04-06 09:57:48
同意@CmdrTchort关于这个问题的答案。
提供这个答案是为了给出一个Write-Verbose自定义实现的实现,这个实现可以被使用(即调用Write-CustomVerbose而不是Write-Verbose )。显然,这不会影响仍然使用Write-Verbose的引用库中的任何现有代码或代码。
function Write-CustomVerbose {
[CmdletBinding(DefaultParameterSetName='UseTimestamp')]
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[AllowEmptyString()]
[string]$Message
,
[Parameter(Mandatory = $false, ParameterSetName='UseTimestamp')]
[string]$TimestampFormat = ((Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern)
,
[Parameter(Mandatory = $false, ParameterSetName='UseTimestamp')]
[switch]$UseLocalTime #defaults to UTC
,
[Parameter(Mandatory = $false, ParameterSetName='DoNotUseTimestamp')]
[switch]$ExcludeTimestamp #defaults to include the timestamp (as that's why we're using this function over the standard write-verbose
)
begin {
[string]$FormattedMessage = '{0}'
if(-not $ExcludeTimestamp.IsPresent) {
$FormattedMessage = "{1:$TimestampFormat}: $FormattedMessage"
}
}
process {
#get the time here rather than in begin as we want it to be accurate per message from pipeline
[DateTime]$Now = Get-Date
if(-not $UseLocalTime.IsPresent){$Now = $Now.ToUniversalTime()}
#output the results
write-verbose ($FormattedMessage -f $Message, $Now)
}
}示例用法:1..1000 | Write-CustomVerbose -Verbose -UseLocalTime -TimestampFormat 'HH:mm'
更新
这里有一个稍微高级一些的版本,允许您一次劫持所有流:
function Write-Custom {
[CmdletBinding(DefaultParameterSetName='UseTimestamp')]
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[PSCustomObject]$InputObject
,
[Parameter(Mandatory = $false, ParameterSetName='UseTimestamp')]
[string]$TimestampFormat = ((Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern)
,
[Parameter(Mandatory = $false, ParameterSetName='UseTimestamp')]
[switch]$UseLocalTime #defaults to UTC
,
[Parameter(Mandatory = $false, ParameterSetName='DoNotUseTimestamp')]
[switch]$ExcludeTimestamp #defaults to include the timestamp (as that's why we're using this function over the standard write-verbose
)
begin {
[string]$FormattedMessage = '{0}'
if(-not $ExcludeTimestamp.IsPresent) {
$FormattedMessage = "{1:$TimestampFormat}: $FormattedMessage"
}
}
process {
#get the time here rather than in begin as we want it to be accurate per message from pipeline
[DateTime]$Now = Get-Date
if(-not $UseLocalTime.IsPresent){$Now = $Now.ToUniversalTime()}
#determine output back to original stream
[bool]$outputStream = $true
if($InputObject.WriteErrorStream) {$outputStream=$false;write-error ($FormattedMessage -f $InputObject, $Now)}
if($InputObject.WriteWarningStream){$outputStream=$false;write-warning ($FormattedMessage -f $InputObject, $Now)}
if($InputObject.WriteVerboseStream){$outputStream=$false;write-verbose ($FormattedMessage -f $InputObject, $Now) -Verbose}
if($InputObject.WriteDebugStream) {$outputStream=$false;write-debug ($FormattedMessage -f $InputObject, $Now) -Debug}
if($outputStream){$InputObject}
}
}
#demo
1..20 | %{
if($_ % 2 -eq 0) {Write-Output $_}
if($_ -eq 11) {Write-Error $_ -ErrorAction Continue 2>&1} #bit of a hack required to get error output to flow further along the pipeline.
if($_ -eq 13) {Write-Warning $_}
if($_ -eq 15) {Write-Verbose $_ -Verbose}
if($_ -eq 17) {Write-Debug $_ -Debug}
} *>&1 | Write-Customhttps://stackoverflow.com/questions/35620301
复制相似问题