我有一个功能可以将脚本中的任何write-hosts
转换为tee
对象(以后将它们保留以用于着色)
function Write-Host($object)
{
$object | tee .\LOG.txt -Append
}
如果文件存在,则当前添加到文件中(如果不存在,则创建一个文件)
我想在每次启动新会话时创建一个。仅在您处于同一会话中时才追加到文件中
我该怎么做?
答案 0 :(得分:1)
这是全局变量有用的少数情况之一,因为它们可以在整个会话中持续存在。在此示例中,我使用它们来设置唯一的文件名(在本例中为今天的日期),以登录到:
function Write-Host($object)
{
if($global:LogFile -eq $null)
{
$global:LogFile = ".\LOG-$(Get-Date -Format 'yyyy-MM-dd').txt"
}
$object | tee $global:LogFile -Append
}
---编辑:---
从注释中,如果您希望在会话开始时有一个新文件并在会话期间追加,我们仍然可以使用全局变量来确定会话的开始,但是我们只是使用检查来删除文件开头,然后将“附加”保留在发球区域:
function Write-Host($object)
{
if($global:LogFile -eq $null)
{
$global:LogFile = ".\LOG.txt"
Remove-Item $global:LogFile -ErrorAction SilentlyContinue
}
$object | tee $global:LogFile -Append
}
---编辑2:---
来自第二条评论:
Remove-Item
是另一种动物,因为默认情况下它没有输出。实际上,获取任何输出的唯一方法是添加-Verbose
参数。但是Tee-Object
不能捕获详细流。为了解决这个问题,我们必须使用两个技巧。首先,我们使用重定向(about_Redirection)指定-Verbose
参数(以获取输出),以将Verbose流(4)重定向到标准Success(1)/ Information流。这将允许Tee-Object
从Remove-Item
cmdlet捕获信息:
Remove-Item test.txt -Verbose 4>&1 | Tee-Object out.txt
答案 1 :(得分:1)
您没有定义新的“会话”给您,所以让我们使用变量$PID
,它是PowerShell运行时的进程ID。
理想情况下,您只需要将此部分作为文件名,以便每个进程都有自己的日志。但是您在评论中表示不想使用多个文件。在这种情况下,请将PID写入文件的第一行,然后每次读取。
function Write-Host($object)
{
$filename = '.\LOG.txt'
$logPID = Get-Content -LiteralPath $filename -ReadCount 1 -ErrorAction Ignore
$newSession = $logPID -ne $PID
if ($newSession) {
$PID | Set-Content -LiteralPath $filename
}
$object | Tee-Object -FilePath $filename -Append
}
答案 2 :(得分:1)
我将为以后的搜索者提供另一种方法。您可以获取当前进程的开始时间,将其与文件创建时间进行比较,如果文件是在当前PID启动之前创建的,则将其删除。
function Write-Host
{
[cmdletbinding()]
Param([parameter(ValueFromPipeline=$true)]$object)
Begin{
$allObjects=New-Object System.Collections.ArrayList
}
Process{
$allObjects.Add($object)|out-null
}
End{
if((test-path .\log.txt) -and (get-item '.\LOG.txt').CreationTime -lt (Get-Process -Id $PID).StartTime){Remove-Item .\LOG.txt}
$allObjects | tee .\LOG.txt -Append
}
}
加上向高级功能的转换,您可以将内容通过管道传递给它,例如:
Get-Process | Write-Host
或者我想最简单的事情就是删除日志文件,就像脚本执行的第一件事一样。