如何使用 PowerShell 将日志从 SharePoint 近乎实时地传送到文件共享?

How do I ship logs from SharePoint in almost real time to a fileshare using PowerShell?

提问人:Dennis 提问时间:2/2/2023 最后编辑:Dennis 更新时间:2/7/2023 访问量:47

问:

我有一个 SharePoint 场,我尝试将日志文件“实时”传送到使用 PowerShell 的监视团队可用的服务器。

我首先使用它运行良好,直到我注意到在其中使用 cmdlet 会自行生成日志条目。我以 1 秒的间隔进行:OGet-SPLogEvent

所以回到我最初的想法,使用那个。 我将日志传送放在一个作业中,该作业在创建较新的日志文件时会中止。 这相当有效,除非我尝试发布的日志文件一开始就很大。Get-Content -Wait

大多数情况下,情况就是这样。我尝试传送的第一个日志文件是空的,并且仅使用第二个日志文件开始传送。

有没有办法在文件大小为 75 - 100 MB 的管道中正常工作?Get-Content -Wait

$SourceLogFolder = <somewhere local>
$LogShipFolder = <somewhere remote>

while ($true) {
  $NewLog = Get-ChildItem $SourceLogFolder | Select -Last 1 #Find the latest log file

  if ($NewLog.Name -ne $CurrentLog.Name) {#the current log file has been closed or is new
    $CurrentLog = $NewLog

    Get-Job | Remove-Job -Force #clear any previous log shippings 

    Start-Job {#Tail CurrentLog
      Get-Content $Using:CurrentLog.FullName -Wait |
        Out-File "$($Using:LogShipFolder)\$($Using:CurrentLog.Name)" -Encoding utf8
    }#end job

  }#end if

  sleep -seconds 30

}#end while
PowerShell SharePoint 监视 日志传送

评论

0赞 Dennis 2/2/2023
当前代码不会检查我是否真的完成了复制所有内容,然后暂时中止日志传送。但这是我即将要解决的一些事情。

答:

0赞 Dennis 2/7/2023 #1

好的,由于某种原因,有时在管道传输大文件时使用新文件之前会创建一次新文件。Out-File

因此,使用将删除创建的 0 字节大已交付日志文件。Out-File -Force

[CmdletBinding()]
param (
    [Parameter(Mandatory)][ValidateNotNullOrEmpty()]
    [string]$SourceLogFolder,

    [Parameter(Mandatory)][ValidateNotNullOrEmpty()]
    [string]$LogShipFolder,

    [int]$CheckInterval = 5, #seconds

    [int]$CleanupTimeSpan = 3 #hours
)

$SourceLogFolder = $SourceLogFolder.TrimEnd('\')
$LogShipFolder = $LogShipFolder.TrimEnd('\')
$ShippedLogName = 'null'

while ($true) {
    $NewLog = Get-ChildItem $SourceLogFolder | Select -Last 1
    $ShippedLog = Get-ChildItem $ShippedLogName -ErrorAction SilentlyContinue

    if (#the current log was closed or is new
        $NewLog.Name -ne $CurrentLog.Name -and
        $ShippedLog.Length -eq $ShippedLogJustNow.Length
    ) {
        $CurrentLog = $NewLog
        $ShippedLogName = "$LogShipFolder\$($CurrentLog.Name)"

        Get-Job | Remove-Job -Force #kill previous log shipping

        Start-ThreadJob {#Tail Current log
            Get-Content ($Using:CurrentLog).FullName -Wait | 
                Out-File $Using:ShippedLogName -Encoding utf8 -Force
        }#end job

        Start-ThreadJob {#Cleanup shipped logs
            $YoungestFileFound = 1

            $OldLogFiles = Get-ChildItem $Using:LogShipFolder -Recurse | 
                where LastWriteTime -le (get-date).AddHours(-$Using:CleanupTimeSpan) | 
                Select -SkipLast $YoungestFileFound

            $OldLogFiles | Remove-Item -Recurse -Force -Confirm:$false
        }#end job

    }#end if

    $ShippedLogJustNow = Get-ChildItem $ShippedLogName -ErrorAction SilentlyContinue
    sleep -Seconds $CheckInterval

    [system.gc]::Collect() #Garbage collect to minimize memory leaks
}#end while

评论

0赞 Dennis 2/7/2023
如果使用的是 PowerShell 5.1,则需要 PSGallery 中的 ThreadJob 模块,或者只使用普通作业。