2016-02-13 48 views
0

我有包含函數Create-RebootData含有子功能,諸如FullFull具有名爲Generate-RebootData子功能在其中創建輸出變量$Global:result的腳本。避免或替代多個位置對象語句

Full以內有多個Where-Object兩條語句按日期和時間過濾$Global:result。下面的例子。

有沒有更簡單的方法來完成這一點,而不是多個Where-Object陳述?

期望的結果是

Set-StrictMode -Version 1.0 
Function Create-RebootData{ 

[CmdletBinding(SupportsShouldProcess=$true,DefaultParameterSetName="ViewOnly")] 
    Param(

[Parameter(ParameterSetName="ViewOnly")] 
    [Switch]$ViewOnly, 

[Parameter(ParameterSetName="Full")] 
    [Switch]$Full, 
    ) 

    Switch ($PSCmdlet.ParameterSetName){ 
"ViewOnly" 
{ 
    ViewOnly 
} 
"Full" 
{ 
    Full 
} 
    }#end switch 

Function Full{ 
Generate-RebootData 

    $Global:result | Where-Object {$_ -like '*fri?2:00*' -and $_.MaintenanceWindow ` 
    -notmatch 'all.da.servers' -and $_.Server -match "^ITD"} | % {"{0}" -f $_.Server} | ` 
    Out-File D:\Scripts\Full-Servers.txt -Append 

    $Global:result | Where-Object {$_ -like '*fri?2:00*' -and $_.MaintenanceWindow ` 
    -notmatch 'all.da.servers' -and $_.Server -match "^ITD"} | ` 
    % {"{0}" -f $_.MaintenanceWindow -replace ` 
    "^NA.+", "$((get-date).AddDays(1).ToString('MM-dd-yy')) 01:50"} | ` 
    Out-File D:\Scripts\Full-Times.txt -Append 

} 

    Function Generate-RebootData{ 
    IF(Get-Command Get-SCOMAlert -ErrorAction SilentlyContinue){}ELSE{Import-Module OperationsManager} 

    "Get Pend reboot servers from prod" 
New-SCOMManagementGroupConnection -ComputerName Server01 

$AlertData = Get-SCOMAlert -Criteria "MyString" | Select NetbiosComputerName 

New-SCOMManagementGroupConnection -ComputerName Server02 

$AlertData += Get-SCOMAlert -Criteria "MyString" | Select NetbiosComputerName 

    "Remove duplicates" 
$AlertDataNoDupe = $AlertData | Sort NetbiosComputerName -Unique 

    "Create hash table" 
$table = @{} 
    "Populate hash table" 

$MaintenanceWindow = Import-Csv D:\Scripts\MaintenanceWindow2.csv 

$MaintenanceWindow | ForEach-Object {$table[$_.Computername] = $_.'Collection Name'} 

    "Create final object" 

$Global:result = @{} 

    "Begin Loop" 
$Global:result = $AlertDataNoDupe | ForEach-Object { [PSCustomObject] @{ 

    Server=$_.NetbiosComputerName 

    MaintenanceWindow= if($table.ContainsKey($_.NetbiosComputerName)){ 
       $table[$_.NetbiosComputerName] 
       }Else { "Not Found!"} 

    PingCheck=IF(Test-Connection -Count 1 $_.NetbiosComputerName -Quiet -ErrorAction SilentlyContinue){"Alive"} 
     ELSE{"Dead"} 

    LastReboot=Try{$operatingSystem = Get-WmiObject Win32_OperatingSystem -ComputerName $_.NetbiosComputerName -ErrorAction Stop 
     [Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)} 
     Catch{"Access Denied!"} 
    } } 
} 
+0

「更簡單」的方法是重構'Generate-RebootData'來獲取像'MaintenanceWindow','Date','Server'這樣的參數。在旁註中,使用全局變量在函數之間交換數據有點代碼味道。爲什麼'Generate-RebootData'不能返回相關的數據集呢? –

+0

我的意圖是創建這個腳本,它將被安排/自動化,並允許它運行以創建同一天的定時重新啓動數據(例如'(Get-Date).AddDays(0)')Generate-RebootData只是收集數據來自SCOM並創建一個變量,用於在星期六或星期天的子功能中使用。 – user4317867

+0

仍然,'$ result = Generate-RebootData'然後將'$ result'傳遞給你的嵌套函數,因爲流水線輸入或參數參數會使你的代碼更容易閱讀,從而更容易維護。作爲一個額外的好處,如果有人在另一個環境中使用腳本而不是原來的腳本,他們將不會讓他們的作用域受到本應保留在這些功能範圍內的數據的污染 –

回答

0

你可以這樣說:

$Global:result | Where-Object { 
    $_ -like '*fri?2:00*' -and 
    $_.MaintenanceWindow -notmatch 'all.da.servers' -and 
    $_.Server -match '^ITD' 
} | ForEach-Object { 
    '{0}' -f $_.Server | Out-File D:\Scripts\Full-Servers.txt -Append 

    '{0}' -f $_.MaintenanceWindow -replace '^NA.+', 
    '{0} 01:50' -f (Get-Date).AddDays(1).ToString('MM-dd-yy') | Out-File D:\Scripts\Full-Times.txt -Append 
} 

但我馬蒂亞斯comment同意,這個功能可能需要重構。

+0

糾正我,如果我錯了,但這種方法需要重複每一天和每個時間的組合。例如星期五1800。 – user4317867

+0

@ user4317867是的,我可能誤解了你的問題:認爲你需要結合兩個'Where-Object'管道的幫助。 – beatcracker

+0

我非常欣賞這些反饋,並會嘗試重構我的功能。 – user4317867