使用每轮循环创建和附加.csv

时间:2018-02-28 22:23:23

标签: powershell exchange-server

因此,我无法将数据附加到功能foreach loop.的csv

我之前创建了静态CSV's,但我重新定义变量这一事实让我发疯了。以下是我的代码所用内容:

[long]$IntSent=0
[long]$IntRec=0
[long]$IntTotal=0
$startdate="02/01/2018 00:00:01"

$domains=@("aaa.com","bbb.com","ccc.com")
$users=@("user1","user2","user3")



ForEach ($user in $users) {
    foreach ($domain in $domains) {
        get-messagetrackinglog -start $startdate  -Recipient $user -resultsize unlimited -EventID Receive | where {[string]$_.sender -like "*@$domain"} |ForEach{$IntRec++}
        #|Where {[String]$_.recipients -notlike "*@belamiecommerce.com*"}

        write-host ($domain, $user , $intrec)
        #Write-host ($IntRec)
        #$IntTotal=$IntSent + $IntRec
        #write-host ($IntTotal)
        [long]$IntRec = 0
    }
}

我希望以下列格式获得输出

aaa.com, user1, value
bbb.com, user1, value
ccc.com, user1, value
aaa.com, user2, value
bbb.com, user2, value

如何在脚本顶部创建文件,然后像疯了一样追加,然后输出?

2 个答案:

答案 0 :(得分:1)

我已将您的foreach循环转换为ForEach-Object管道。它更容易使用。

此外,所有临时变量和计数/递增似乎都不是必需的。 Powershell非常适合.Count件事。

由于您只需要为每个用户查询一次日志,因此请将Get-MessageTrackingLog移出内部循环以节省一些时间。如果Get-MessageTrackingLog实际上接受多个-Recipient,请查看文档,您可以完全将其移出循环。

只需编写一些以逗号分隔的值,即可轻松定义PowerShell中的数组。此处不需要@()

在内部循环中创建[pscustomobject]使Powershell打印出一个漂亮的表,它们与ConvertTo-CSV cmdlet兼容。请注意,您在{block}中创建的任何值都将成为该块的返回值的一部分。以下脚本如何创建其$result

$startdate="02/01/2018 00:00:01"
$domains="aaa.com","bbb.com","ccc.com"
$users="user1","user2","user3"

$result = $users | ForEach-Object {
    $user = $_
    $log = Get-MessageTrackingLog -start $startdate -Recipient $user -resultsize unlimited -EventID Receive
    $domains | ForEach-Object {
        $domain = $_
        [pscustomobject]@{
            domain = $domain
            user = $user
            messages = ($log | Where-Object sender -like "*@$domain").Count
        }
    }
}

# output $result to screen...
$result

# ...or output it to a file
$result | ConvertTo-Csv -NoTypeInformation | Out-File "mesages.csv" -Encoding utf8 

使用Where-Object { $_.sender.ToString().EndsWith("@$domain") }可能会比-like "*@$domain"更快。

答案 1 :(得分:0)

这不是一个完整的答案,但应该让你开始。

在循环开始之前创建一个arraylist,将循环的每次迭代的输出添加到数组中,然后在循环之后将数组导出到csv文件。

[long]$IntSent=0
[long]$IntRec=0
[long]$IntTotal=0
$startdate="02/01/2018 00:00:01"

$domains=@("aaa.com","bbb.com","ccc.com")
$users=@("user1","user2","user3")
$Arr = New-Object -TypeName System.Collections.ArrayList


ForEach ($user in $users) 
{
    foreach ($domain in $domains) 
    {
        get-messagetrackinglog -start $startdate  -Recipient $user -resultsize unlimited -EventID Receive | where {[string]$_.sender -like "*@$domain"}|ForEach{[void]$Arr.Add($_)}
    }
}

$Arr | Export-Csv -Path C:\file

或创建一个函数,将其回调并将其传递到Export-Csv

[long]$IntSent=0
[long]$IntRec=0
[long]$IntTotal=0
$startdate="02/01/2018 00:00:01"

$domains=@("aaa.com","bbb.com","ccc.com")
$users=@("user1","user2","user3")

function do-task
{
    param
    (
        [string[]]$Users,
        [String[]]$Domains
    )

    ForEach ($user in $users) 
    {
        foreach ($domain in $domains) 
        {
            get-messagetrackinglog -start $startdate  -Recipient $user -resultsize unlimited -EventID Receive | where {[string]$_.sender -like "*@$domain"}|ForEach{[void]$Arr.Add($_)}
        }
    }
}

do-task -User $users -Domains $domains | Export-Csv -Path c:\file