2013-11-26 71 views
6

有沒有辦法讓腳本跳轉到特定位置,例如:命令提示符中的GOTO?我想在腳本結束時跳轉到開頭。跳轉到腳本中的某些位置

$tag1 = Read-Host 'Enter tag #' 

cls 

sc.exe \\$tag1 start RemoteRegistry 

cls 

Start-Sleep -s 2 

cls 

systeminfo /S $tag1 | findstr /B /C:"OS Name" /C:"System Boot Time" /C:"System Up Time"; 


Get-EventLog system -computername $tag1 -InstanceId 2147489657 -Newest 10 | ft EventID,TimeWritten,MachineName -AutoSize 

Pause 
+1

轉到是邪惡的,請改用其他邏輯結構。這聽起來像你正在尋找一個循環。 – SBI

+0

任何示例?我不是那個親。 – Aaron

回答

8

這裏是和使用的腳本示例:

$GetInfo = { 
    $tag1 = Read-Host 'Enter tag # or Q to quit' 
    if ($tag1 -eq 'Q'){Return} 
    cls 
    sc.exe \\$tag1 start RemoteRegistry 
    cls 
    Start-Sleep -s 2 
    cls 
    systeminfo /S $tag1 | findstr /B /C:"OS Name" /C:"System Boot Time" /C:"System Up Time" 
    Get-EventLog system -computername $tag1 -InstanceId 2147489657 -Newest 10 | 
    ft EventID,TimeWritten,MachineName -AutoSize 
    .$GetInfo 
} 

&$GetInfo 

使用。而不是腳本塊中的&,以防止其在調用堆棧中行走。

將代碼放入腳本塊中以後從腳本中的任意點調用(模擬GoTo)在功能上與使用函數相同,並且以這種方式使用的腳本塊有時稱爲「匿名函數」。

+0

因此,要獲得systeminfo命令和Get-EventLog命令同時運行,我只需要將它放在不使用;符號的不同行上? – Aaron

+0

很多。把每一個放在它自己的腳本塊中,分配給它自己的變量,以及點源變量來運行它 – mjolinor

+0

Q知道如何退出?或者我沒有看到什麼? – Aaron

5

在PowerShell中沒有轉到,沒有人會錯過它:)。只需將這些命令包裝在一個循環中或其他東西中即可。

或者嘗試以下操作。您可以將命令列表分配給一個變量,然後使用&$varname執行它們。但它仍然沒有轉到。

$commands = { 

    Write-Host "do some work" 

    $again = Read-Host "again?" 
    if ($again -eq "y"){ 
     &$commands 
    } else { 
     Write-Host "end"  
    } 
} 

&$commands 
+0

我用我的腳本更新了OP。不知道我如何將它與你所擁有的結合起來。 – Aaron

+2

這需要相當先進的知識來使用第一級腳本塊。目的並不明顯或清楚,它是一個循環。它會消耗資源,直到達到動態呼叫深度限制,然後鎖定並在某些不可預知的時間拋出異常並停止循環。你確定你更喜歡這個設計:「啓動goto start」嗎? – TessellatingHeckler

+0

我想念goto's,他們不只是爲了循環。我根據某些錯誤或結果使用它們進行重定向,而不必離開當前的方法。我也同意@TessellatingHeckler,「GoTo」的純英文似乎比這個新架構更明顯。當試圖破譯別人寫的腳本時,更明顯可以減少開發時間;他們可能會或可能不會是不同的技能水平。 –

3

腳本的另一種變體,有一些來自@ mjolinor的想法。我也轉而使用systeminfo,因爲至少在我的電腦上,它比使用適用的WMI查詢要慢

while (1) { 
    $tag1 = Read-Host 'Enter tag # or Q to quit' 
    if ($tag1 -eq "Q") { 
     break; 
    } 
    sc.exe \\$tag1 start RemoteRegistry; 
    start-sleep -seconds 2 
    $OSInfo = get-wmiobject -class win32_operatingsystem -computername $tag1; 
    $OSInfo | Format-Table -Property @{Name="OS Name";Expression={$_.Caption}},@{Name="System Boot Time";Expression={$_.ConvertToDateTime($_.LastBootUpTime)}},@{Name="System Uptime (Days)";Expression={[math]::Round((New-TimeSpan -Start $_.converttodatetime($_.LastBootUpTime)|select-object -expandproperty totaldays),2)}} -AutoSize; 
    Get-EventLog system -computername $tag1 -InstanceId 2147489657 -Newest 10 | format-table EventID,TimeWritten,MachineName -AutoSize 
} 

我不能肯定WMI需要遠程註冊表,所以你也許可以消除sc.exe線和sleep乾脆。除非你需要它的東西。

+0

這樣做有趣的方式。還有更多的代碼。將不得不通過更多。 – Aaron

+0

運行它,看看你得到了什麼。它可能似乎是「更多的代碼」(這很少是一個有價值的指標,BTW),但get-wmiobject方法應該比systeminfo更快,並且最終的結果是格式化的(格式化佔用了很多「額外」代碼)。 – alroc

+0

如果系統是64位,該怎麼辦?我看到它說win32那裏? – Aaron