ค้นหาเว็บไซต์

จับเอาต์พุต Verbose โดยทางโปรแกรมในตัวแปร PowerShell


วันก่อนฉันกำลังเล่นกับ cmdlets ในโมดูล DFSR และพบว่าไม่มีใครสามารถ (เท่าที่ฉันสามารถบอกได้) ที่สามารถให้จำนวนรายการใน Backlog ของ DFSR ได้อย่างน่าเชื่อถือ

แผนของฉันคือการเริ่มต้นการจำลองแบบของสองโฟลเดอร์ จากนั้นให้สคริปต์ตรวจสอบรายการงานที่ค้างเพื่อสร้างข้อความสถานะเพื่อแจ้งให้ฉันทราบถึงความคืบหน้า

ฉันค้นหาวิธีที่จะทำสิ่งนี้ให้สำเร็จโดยดูที่คำสั่งในโมดูล DFSR ที่มีคำกริยา Get

PS C:> รับคำสั่ง - โมดูล DFSR - รับกริยา

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Get-DfsrBacklog                                    DFSR
Cmdlet          Get-DfsrCloneState                                 DFSR
Cmdlet          Get-DfsrConnection                                 DFSR
Cmdlet          Get-DfsrConnectionSchedule                         DFSR
Cmdlet          Get-DfsReplicatedFolder                            DFSR
Cmdlet          Get-DfsReplicationGroup                            DFSR
Cmdlet          Get-DfsrFileHash                                   DFSR
Cmdlet          Get-DfsrGroupSchedule                              DFSR
Cmdlet          Get-DfsrIdRecord                                   DFSR
Cmdlet          Get-DfsrMember                                     DFSR
Cmdlet          Get-DfsrMembership                                 DFSR
Cmdlet          Get-DfsrPreservedFiles                             DFSR
Cmdlet          Get-DfsrServiceConfiguration                       DFSR
Cmdlet          Get-DfsrState                                      DFSR

Get-DfsrBacklog ดูเหมือนกับสิ่งที่ฉันกำลังมองหา เพียงเพื่อให้แน่ใจว่าฉันได้ดูความช่วยเหลือสำหรับ cmdlet นั้น

และรู้สึกประหลาดใจเล็กน้อยเมื่อรู้ว่ามันจะส่งคืนอ็อบเจ็กต์ 100 รายการแรก ในบันทึกที่ค้างในการจำลองของฉัน

เยี่ยมมาก แต่ถ้าฉันต้องการจำนวนทั้งหมดล่ะ มีสินค้าในมือหลายร้อยหรือล้านรายการ? ไม่มีทาง (ที่ฉันหาได้) ที่จะส่งคืนจำนวนอ็อบเจ็กต์ทั้งหมดใน Backlog แต่หากใช้สวิตช์ -Verbose คำสั่งจะเขียนข้อความไปยังสตรีม Verbose โดยระบุสิ่งที่คล้ายกับ:

โฟลเดอร์ที่ถูกจำลองแบบมีไฟล์ค้างอยู่ โฟลเดอร์ที่จำลองแบบ: “ReplFolder ” จำนวน: 46314

หรือ

ไม่มี Backlog สำหรับโฟลเดอร์ที่จำลองแบบชื่อ “ReplFolder”

แล้วก็มีคน! ใครๆ ก็สามารถรันคำสั่งและอ่านข้อความโดยละเอียดได้ ทุกคนยกเว้นสคริปต์ของฉันซึ่งไม่สนใจสตรีม Verbose เลย หรือไม่?

นี่คือจุดที่ฟีเจอร์เล็กๆ น้อยๆ ที่ยอดเยี่ยมใน PowerShell ที่เรียกว่าการเปลี่ยนเส้นทางมีประโยชน์ คุณลักษณะนี้ถูกนำมาใช้แล้วใน Powershell เวอร์ชัน 2.0 แต่ในตอนนั้นถูกจำกัดให้เปลี่ยนเส้นทางเพียงสองสตรีมเท่านั้น นั่นคือ Success Output (เอาต์พุตทั่วไปที่ฉันมักจะเรียกว่าไปป์ไลน์) และ Steam ของข้อผิดพลาด ใน Powershell เวอร์ชัน 3.0 มีประสิทธิภาพมากยิ่งขึ้น และตอนนี้เราสามารถกำหนดทิศทางเอาท์พุตสตรีมใดก็ได้จากห้าสตรีม (ความสำเร็จ ข้อผิดพลาด คำเตือน รายละเอียด และดีบัก) ไปยังสตรีมเอาท์พุตที่สำเร็จหรือไปยังไฟล์ที่เราเลือกโดยใช้ตัวดำเนินการเปลี่ยนเส้นทาง '>' . ไวยากรณ์นั้นง่าย ขั้นแรกให้ป้อนหมายเลขของเอาต์พุตสตรีมที่ควรเปลี่ยนเส้นทางจากตารางด้านล่าง ตามด้วยตัวดำเนินการ > และเป้าหมายของการเปลี่ยนเส้นทาง

<td valign="top" width="137">
  All output
</td>
<td valign="top" width="137">
  Success output
</td>
<td valign="top" width="137">
  Errors
</td>
<td valign="top" width="137">
  Warning messages
</td>
<td valign="top" width="137">
  Verbose output
</td>
<td valign="top" width="137">
  Debug messages
</td>
*
1
2
3
4
5

เพื่อทดสอบสิ่งนี้ ฉันเขียนฟังก์ชันที่จะส่งข้อความไปยังสตรีมต่างๆ

function Write-ToStreams
{
    [cmdletbinding()]
    Param()
    Begin
    {
        $VerbosePreference = 'Continue'
        $DebugPreference = 'Continue'
    }
    Process
    {
        Write-Host "This is written to host" -ForegroundColor Green
        Write-Output "This is written to Success output"
        Write-Error "This is an error"
        Write-Warning "This is a warning message"
        Write-Verbose "This is verbose output"
        Write-Debug "This is a debug message"
    }
}

ซึ่งให้ผลลัพธ์ต่อไปนี้แก่ฉัน:

ตอนนี้ถ้าฉันต้องการเปลี่ยนเส้นทางเอาต์พุตแบบละเอียด ฉันจะสิ้นสุดคำสั่งด้วยหมายเลขของสตรีมเอาต์พุตแบบละเอียด '4' ตามด้วยตัวดำเนินการเปลี่ยนเส้นทาง '>' และเป้าหมายของการเปลี่ยนเส้นทางของฉัน

อีกทางเลือกหนึ่งคือเปลี่ยนเส้นทางสตรีมเอาท์พุตหนึ่งไปยังสตรีมเอาท์พุตที่สำเร็จโดยใช้ &1 เป็นเป้าหมายดังนี้:

ซึ่งดูเหมือนกับครั้งแรกที่เรารันคำสั่งเลย! แต่คราวนี้ข้อความโดยละเอียดถูกเขียนไปยังเอาท์พุตสตรีมจริงๆ

เพื่อทดสอบสิ่งนี้ ให้เก็บเอาต์พุตไว้ในตัวแปร:

และนี่คือคำตอบสำหรับปัญหาของฉันเกี่ยวกับจำนวนไฟล์ใน DFSR Backlog ฉันแค่ต้องแยกเอาต์พุตเริ่มต้นออกจากเอาต์พุตแบบละเอียด

ดังนั้นให้เริ่มต้นใหม่ด้วยการรันฟังก์ชัน Write-ToStreams และจัดเก็บเอาต์พุตในตัวแปรโดยไม่มีการเปลี่ยนเส้นทาง:

$Output=เขียน-ToStreams

สิ่งนี้จะส่งข้อความไปยังสตรีมทั้งหมด ยกเว้นผลลัพธ์ Success ซึ่งจะถูกดักจับโดยตัวแปร $Output ของฉัน ในการรับสตรีมอื่น ๆ ฉันใช้คุณสมบัติอื่นที่เรียกว่าการแสดงออกย่อย นิพจน์ย่อยเปรียบเสมือนตัวแปรที่ใช้สคริปต์ เช่น โดยการเขียน $ (Get-Date -f $FormatString) โค้ดภายในวงเล็บจะถูกดำเนินการ และผลลัพธ์จะถูกส่งกลับเหมือนกับที่มาจากตัวแปร โดยการใส่ตัวอย่างก่อนหน้าไว้ในนิพจน์ย่อย เราได้รับโอกาสในการเปลี่ยนเส้นทางเอาต์พุตแบบละเอียดและบันทึกลงในตัวแปรอื่นดังนี้:

$VerboseMessage=$ ($Output=เขียน-ToStreams) 4>&1

ซึ่งสามารถทำซ้ำได้สำหรับสตรีม Error, Warning และ Debug สามสตรีมที่เหลือ สิ่งสำคัญมากที่ต้องสังเกตที่นี่คือข้อความสีเขียวที่สร้างโดย Write-Host ข้อความนี้ไม่สามารถเปลี่ยนเส้นทางหรือบันทึกได้เลย ซึ่งทำให้ Write-Host เป็นสิ่งที่ควรใช้ก็ต่อเมื่อมีเจตนาที่จะเขียนบางสิ่งลงบนหน้าจอและไม่เคยเป็นผลลัพธ์จริงเลย ใช้สตรีมอื่นๆ สำหรับเอาต์พุต

เพื่อกลับไปที่ปัญหาของฉันเกี่ยวกับจำนวนรายการใน Backlog ของ dfsr ฉันเขียนสคริปต์ที่จะส่งคืนจำนวนรายการใน Backlog สำหรับแต่ละโฟลเดอร์ที่จำลองแบบโดยใช้เทคนิคนี้ และมีอยู่ใน Technet Gallery

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนเส้นทาง โปรดดูบทความช่วยเหลือ about_Redirection

บทความที่เกี่ยวข้อง