Tìm kiếm trang web

Lời nhắc giám sát PowerShell khác


Ồ. Tất cả các bạn có thích lời nhắc của PowerShell hay không? Lời nhắc hiển thị thông tin lên/xuống của tôi rất phổ biến. Thêm vài cái nữa thì sao? Như tôi đã đề cập trong bài viết trước, hiệu suất là cực kỳ quan trọng khi nói đến chức năng nhắc nhở PowerShell. Tôi đã thử nghiệm một số kỹ thuật khác nhau và tôi nghĩ sử dụng không gian chạy và bảng băm được đồng bộ hóa là cách tốt nhất. Với ý nghĩ đó, đây là một số chức năng nhắc nhở PowerShell khác.

Đầu tiên là lời nhắc hiển thị phần trăm dung lượng đĩa trống cho ổ C: trên một hoặc nhiều máy tính từ xa. Tôi đang sử dụng Get-Volume để lấy thông tin này. Trong hàm trước, tôi đã mã hóa cứng tên máy tính. Trong phiên bản này, tôi đặt chúng vào một tệp văn bản trong thư mục Tập lệnh của mình. Trong vòng lặp Do, tôi lấy danh sách, lọc ra các dòng trống và cắt bớt khoảng trắng.

$computers = Get-Content -Path c:\scripts\watch.txt | where-object {$_ -match $_} |
foreach-object {$_.trim()}
$results = $computers | ForEach-Object {
try {
    $c = Get-Volume -DriveLetter c -CimSession $_ -ErrorAction Stop |
        Add-Member -MemberType ScriptProperty -Name PctFree -Value {($($this.SizeRemaining) / $($this.size)) * 100 -as [int]} -Force -passthru
    $val = $c.PctFree
}
Catch {
    $val = '??'
}

Bây giờ tôi có thể tự động thay đổi lời nhắc bằng cách sửa đổi tệp văn bản. Khi lời nhắc được tải lần đầu tiên, bảng băm không có giá trị nên tôi hiển thị 'đang hoạt động'. Khi có dữ liệu, lời nhắc sẽ phản ánh phần trăm dung lượng trống.

Vì tôi cho rằng dung lượng ổ đĩa không thay đổi nhanh chóng nên vòng lặp trong vùng chạy chỉ chạy mỗi phút một lần. Giống như các hàm nhắc nhở khác của tôi, mã này có trên GitHub.

SpacePrompt.ps1:

function prompt {

    Try {
        Get-Variable -Name rsHash -Scope global -ErrorAction Stop | Out-Null
    }
    Catch {
        #create the runspace and synchronized hashtable
        $global:rsHash = [hashtable]::Synchronized(@{Computername = $env:computername; results = ""; date = (Get-Date)})
        $newRunspace = [runspacefactory]::CreateRunspace()
        #set apartment state if available
        if ($newRunspace.ApartmentState) {
            $newRunspace.ApartmentState = "STA"
        }
        $newRunspace.ThreadOptions = "ReuseThread"         
        $newRunspace.Open()
        $newRunspace.SessionStateProxy.SetVariable("rsHash", $rsHash)  

        $pscmd = [PowerShell]::Create().AddScript( {  

                do {
                    #define the list of computers to test
                    #filter out blank lines and trim any spaces to clean up names.
                    $computers = Get-Content -Path c:\scripts\watch.txt | where-object {$_ -match $_} |
                        foreach-object {$_.trim()}
                    $results = $computers | ForEach-Object {
                        try {
                            $c = Get-Volume -DriveLetter c -CimSession $_ -ErrorAction Stop |
                                Add-Member -MemberType ScriptProperty -Name PctFree -Value {($($this.SizeRemaining) / $($this.size)) * 100 -as [int]} -Force -passthru
                            $val = $c.PctFree
                        }
                        Catch {
                            $val = '??'
                        }
                        [pscustomobject]@{
                            Computername = $_.toupper()
                            PctFree      = $val
                        }
                    }

                    $global:rsHash.results = $results
                    $global:rsHash.date = Get-Date
                    #set a sleep interval between tests
                    Start-Sleep -Seconds 60
                } while ($True)

            })

        $pscmd.runspace = $newrunspace
        [void]$psCmd.BeginInvoke()

    } #catch

    Write-Host "[" -NoNewline
  
    if ($global:rshash.results) {
        $global:rshash.results | Sort-Object -Property Computername |
            ForEach-Object {
            if ($_.pctfree -eq '??') {
                $fg = "magenta"
            }
            elseif ($_.pctfree -le 20) {
                $fg = "red"
            }
            elseif ($_.pctfree -le 50) {
                $fg = "yellow"
            }
            else {
                $fg = "green"
            }
            Write-Host $_.computername -NoNewline
            Write-Host " $($_.pctfree)% " -ForegroundColor $fg -NoNewline
        } #foreach data item
    } #if results  
    else {
        Write-Host "working..." -NoNewline -ForegroundColor Cyan
    }

    Write-Host "]" -NoNewline

    "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
}

Nhưng xin chờ chút nữa! Thế còn một biến thể để hiển thị phần trăm bộ nhớ còn trống thì sao? Phiên bản này cũng sử dụng danh sách máy tính của tôi. Nhưng để hiệu quả hơn, tôi tạo PSSessions cho từng máy tính. Điều này cho phép tôi chạy Invoke-Command để lấy thông tin từ lớp Win32_OperatingSystem thông qua Get-CimInstance theo cách hiệu quả hơn. Vấn đề tôi gặp phải là nguyên nhân khiến máy chủ ngừng hoạt động hoặc không khả dụng. Trong chức năng của mình, tôi loại bỏ các PSSessions bị hỏng và tạo các phiên mới cho các máy tính trong danh sách chưa có phiên mở. Điều tôi chưa tính đến là xóa một máy tính khỏi danh sách và xóa phiên trong lời nhắc. Bạn có thể thêm mã đó nếu muốn. Ngoài ra, chỉ cần cập nhật danh sách và xóa biến $rshash. Hoặc khởi động lại phiên PowerShell của bạn.

Chức năng này có thể được tìm thấy trực tuyến ở đây.

MemUsagePrompt.ps1:

function prompt {

    Try {
        Get-Variable -Name rsHash -Scope global -ErrorAction Stop | Out-Null
    }
    Catch {
        #create the runspace and synchronized hashtable
        $global:rsHash = [hashtable]::Synchronized(@{Computername = $env:computername; results = ""; date = (Get-Date)})
        $newRunspace = [runspacefactory]::CreateRunspace()
        #set apartment state if available
        if ($newRunspace.ApartmentState) {
            $newRunspace.ApartmentState = "STA"
        }
        $newRunspace.ThreadOptions = "ReuseThread"         
        $newRunspace.Open()
        $newRunspace.SessionStateProxy.SetVariable("rsHash", $rsHash)  

        $pscmd = [PowerShell]::Create().AddScript( {                      
                    
                #define a pssession option to speed up connections
                $opt = New-PSSessionOption -OpenTimeout 1000 -MaxConnectionRetryCount 1

                do {
                    #define the list of computers to test
                    #filter out blank lines and trim any spaces to clean up names.
                    $computers = Get-Content -Path c:\scripts\watch.txt | 
                        Where-Object {$_ -match $_} |
                        Foreach-Object {$_.trim()}

                    #make sure there are sessions for all computers in the list
                    $computers | Where-Object {(get-pssession).where( {$_.state -eq 'opened'}).computername -notcontains $_} |
                        ForEach-Object {
                        New-PSSession -ComputerName $_ -SessionOption $opt
                        }
                    #remove broken sessions
                    Get-PSSession | Where-Object {$_.state -eq 'broken'} | Remove-PSSession
                   
                    $data = Invoke-command -ScriptBlock {
                        Get-CimInstance -ClassName win32_operatingsystem -Property TotalVisibleMemorySize, FreePhysicalMemory
                    } -Session (Get-PSSession) 

                    $results = $data | Sort-Object -Property PSComputername |
                        ForEach-Object {
                        [int]$val = ($_.FreePhysicalMemory / $_.TotalVisibleMemorySize) * 100

                        [pscustomobject]@{
                            Computername = $_.PSComputername.toUpper()
                            PctFree      = $val
                        }
                    }

                    $global:rsHash.results = $results
                    $global:rsHash.date = Get-Date
                    #set a sleep interval between tests
                    Start-Sleep -Seconds 10
                } while ($True)

            })

        $pscmd.runspace = $newrunspace
        [void]$psCmd.BeginInvoke()

    } #catch
      
    Write-Host "FreeMem"
    Write-Host "[" -NoNewline

    if ($global:rshash.results) {
        $global:rshash.results | Sort-Object -Property Computername |
            ForEach-Object {
            if ($_.pctfree -le 30) {
                $fg = "red"
            }
            elseif ($_.pctfree -le 60) {
                $fg = "yellow"
            }
            else {
                $fg = "green"
            }
            Write-Host " $($_.computername) " -NoNewline
            Write-Host "$($_.pctfree)%" -ForegroundColor $fg -NoNewline
        } #foreach data item
    } #if results  
    else {
        Write-Host "working..." -NoNewline -ForegroundColor Cyan
    }
        
    Write-Host " ]" -NoNewline

    "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
    
}

Tôi đang xử lý một lời nhắc đo từ xa toàn diện hơn. Tôi thích vượt qua các ranh giới và điều này chắc chắn là cực đoan. Cảm ơn sự nhiệt tình của bạn. Thưởng thức.

Bài viết liên quan