Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jumping around to certain spots in script

Tags:

powershell

Is there a way to make a script jump to a specific spot like :GOTO in command prompt? I wanted to make the script jump to the beginning when it is ended.

$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
like image 1000
Aaron Avatar asked Nov 26 '13 15:11

Aaron


3 Answers

There's no goto in PowerShell, and nobody misses it :). Just wrap the block of commands in a loop or something.

Or try the below. You can assign list of commands to a variable, and then execute them with &$varname. It's still not goto, though.

$commands = {

    Write-Host "do some work"

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

&$commands 
like image 104
AdamL Avatar answered Nov 16 '22 01:11

AdamL


Here's and example using your script:

$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

Use . instead of & inside the script block to prevent it from walking up the call stack.

Putting code into script blocks to be called later from arbitrary points in the script (emulating a GoTo) is functionally the same as using a function, and script block used in this manner are sometimes referred to as "anonymous functions".

like image 41
mjolinor Avatar answered Nov 16 '22 01:11

mjolinor


Another variation on the script with some ideas taken from @mjolinor. I also switched away from using systeminfo because at least on my computer, it's much slower than using the applicable WMI query.

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
}

I'm not certain that WMI needs remote registry, so you might be able to eliminate the sc.exe line and sleep altogether. Unless you need it for something else.

like image 30
alroc Avatar answered Nov 16 '22 00:11

alroc