当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 小测验

作者:精品下载站 日期:2024-12-14 07:51:33 浏览:14 分类:玩电脑

PowerShell 小测验


我一直在寻找方法来帮助教授 PowerShell,有一天我想为什么不让 PowerShell 来教你呢?我创建了一个 PowerShell 脚本,可以动态生成有关计算机上安装的 cmdlet 和函数的测验。简而言之,测验问题会向您显示命令概要,然后呈现可能答案的菜单。您选择答案。考虑到命令名称的动词-名词模式,这“应该”很容易,但您可能会感到惊讶。

目前,测验采用独立脚本。在某些时候,我很可能会将其添加到我的 PSTeachingTools 模块中,您可以从 PowerShell Gallery 安装该模块。该脚本有帮助,因此下载后您可以获得它:

help C:\scripts\PSquiz.ps1 -full

默认情况下,该脚本将从计算机上安装的模块中查找具有正确定义的概要的所有 cmdlet 和函数。我尝试添加一些过滤来处理有问题的命令或那些没有帮助的命令。您还可以排除一个或多个模块,并且允许使用通配符。或者,您可以指定特定的模块。脚本构建命令缓存后,它会自动生成一个问题并提示您回答:

[玩转系统] PowerShell 小测验

如果您回答错误,脚本将显示正确答案。要继续回答另一个问题,请按任意键。该脚本将跟踪您的进度,当您最终退出时,显示颜色编码的摘要结果。

[玩转系统] PowerShell 小测验

目前,您可以在此处找到该脚本。

#requires -version 5.0

#PSQuiz.ps1

<#
.Synopsis
Run a PowerShell quiz
.Description
Use this script to test your knowledge of PowerShell commands, which given the Verb-Noun naming pattern should be pretty easy.

The default behavior is to use all cmdlets and functions from installed modules with an option to exclude an array of module names. Wildcards are allowed. You also have the option to specify a single module for testing.
.Example
PS C:\> c:\scripts\PSQuiz.ps1

PowerShell Pop Quiz

Given this short cmdlet description:

 Creates a new System.Windows.Markup.RoutedEventConverter

 What command would you use?

  [1]   Invoke-CauScan
  [2]   Clear-Tpm
  [3]   Remove-WindowsCapability
  [4]   Get-IscsiTargetServerSetting
  [5]   New-RoutedEventConverter

Select a menu choice [1-5]: 5

You are Correct!!

Do you want another question? Press any key to continue or Q to quit: q
Your scored 1 correct out of 1 [100.00 %]
.Example
PS C:\> c:\scripts\PSQuiz.ps1 -module Hyper-V

Launch the quiz but only use commands from the Hyper-V module.

.Example
PS C:\> c:\scripts\PSQuiz.ps1 -exclude ISE,WPK,my*

Launch the quiz using all modules except ISE, WPK and any modules that start with 'my'.
.Link
Get-Help
.Link
Get-Command
.Notes
Version 0.9

Learn more about PowerShell:
Essential PowerShell Learning Resources


#>
[cmdletbinding(DefaultParameterSetName = "all")]
Param(
    [Parameter(ParameterSetName = "single")]    
    [ValidateScript( {Get-Module $_ -list})]
    #You can specify a single module for testing. The default is all modules.
    [string]$ModuleName,
    [Parameter(ParameterSetName = "all")]
    #Enter a comma separated list of module names to ignore. You can use wildcards.
    [string[]]$Exclude,
    #This is used to indicate a continuing test. You should never need to use this parameter.
    [switch]$NextQuestion
)

Clear-Host
Write-Verbose "Starting $($myinvocation.MyCommand)"
Write-Verbose "PSBoundparameters:"
write-verbose ($psboundparameters | out-string)

if (-Not $NextQuestion) {
    Write-Verbose "First question setup"
    #initialize some variables to keep track of correct answers
    $global:QuestionCount = 0
    $global:CorrectCount = 0
    $global:CommandCache = @()

    if ($ModuleName) {
        $Status = "Getting commands from module $modulename."
        Write-Verbose $Status
        Write-Progress -Activity $myinvocation.MyCommand -Status $status -CurrentOperation "Please wait..."
        $global:CommandCache = Get-command -CommandType Cmdlet,Function -Module $ModuleName   
        
    }
    else {
        $status = "Getting commands from all available modules."

        if ($exclude) {
            $status += " Excluding these modules: $($exclude -join ',') "
            #define a separate filter because this causes a problem in PowerShell v6 if $exclude is not specified
            $filter = {$_.Source -AND $_.source -notmatch $($exclude -join '|')}
        }
        else {
            $filter = {$_.Source}
        }
        Write-Verbose $status
        Write-Progress -Activity $myinvocation.MyCommand -Status $status -CurrentOperation "Please wait..."
        #get cmdlets and function that have a defined source which should be a module or snapin
        $global:CommandCache = (Get-command -CommandType Cmdlet,Function).Where($filter)
    }
    Write-Progress -Activity  $myinvocation.MyCommand -Completed
    Write-Verbose "Added $(($global:commandCache).count) commands to the command cache"
    if ((($global:commandCache).count) -eq 0) {
        Write-Warning "Failed to find commands in any matching modules."
        #bail out
        Return
    }
}
else {
    Write-Verbose "Continuing the quiz"
    Write-Verbose "Current question count: $($global:QuestionCount)"
    Write-Verbose "Current correct count: $($global:CorrectCount)"
    Write-Verbose "Current command cache: $(($global:commandCache).count)"
}

#select a random command with a legitimate synopsis
Write-Verbose "Selecting a random command"
do {
    $cmd = $global:CommandCache | Get-Random
    $synopsis = ($cmd | Get-Help).synopsis

} until ($synopsis -notmatch "(This cmdlet is not supported)|\[|(Fill in the Synopsis)" -AND $synopsis -match "\w{4,}")

#get other noun related commands
[object[]]$commands = @($cmd)
$commands += get-command -noun $cmd.noun | Where-Object {$_.name -ne $cmd.name} | Select-Object -first 4

#get additional random commands if there are not enough noun-related
if ($commands.count -lt 5) {
    Write-Verbose "Getting supplemental commands for answers"
    While ($commands.count -lt 5) {
        $add = Get-command -CommandType Cmdlet | Get-Random |
            Where-Object {$commands.name -notcontains $_.name}
        $commands += $add
    }
}
#randomize
$commands = $commands | get-random -count $commands.count

$Title = "PowerShell Pop Quiz"
$Cue = @"

Given this short cmdlet description: 

 $synopsis

 What command would you use?


"@

for ($i = 1; $i -lt $commands.count + 1; $i++) {

    $Cue += "  [$i]`t$($commands[$i-1].Name)`n"
}

Write-host $Title -ForegroundColor Cyan
Write-Host $Cue -ForegroundColor Yellow

Do {
    try {
        [validaterange(1, 5)][int32]$r = Read-Host -prompt "Select a menu choice [1-5]" -erroraction stop
        write-verbose "You entered $r"
    }
    Catch {
        #ignore the error
        write-warning $_.exception.message
        $r = 0
    }
} Until ($r -ge 1 -AND $r -le 5)

#increment the question counter
$global:QuestionCount++
if ($commands[$r - 1].name -eq $cmd.Name) {
    $global:CorrectCount++
    Write-Host "`nYou are Correct!!" -foregroundcolor green
}
else {
    Write-Host "`nThe correct answer is $($cmd.name)" -foregroundcolor Red
}

[string]$s = Read-Host "`nDo you want another question? Press any key to continue or Q to quit"
if ($s -match "^q") {
    $score = ($global:CorrectCount / $global:QuestionCount)
    $result = "Your scored {0} correct out of {1} [{2:p2}]" -f $global:CorrectCount, $global:QuestionCount, $score
    #colorize output based on score
    if ($score -ge .80) {
        $fg = "green"
    }
    elseif ($score -ge .40) {
        $fg = "yellow"
    }
    else {
        $fg = "red"
    }
    Write-Host $result -ForegroundColor $fg
    Remove-Variable CorrectCount, QuestionCount,CommandCache -Scope global
} 
else {
    if (-Not ($psboundParameters.containsKey("NextQuestion"))) {
            Write-Verbose "Flagging for next question"
            $psboundparameters.add("NextQuestion", $True)
        }
        Write-Verbose "Invoking quiz"
        #Write-verbose ($myinvocation.mycommand | out-string)
        &$($myinvocation.mycommand) @PSBoundParameters
        
    }

我希望你能尝试一下,如果你遇到错误,请告诉我。也对任何可以使其更有用的增强感兴趣。我已经想到了一些,但我想获得一些关于核心功能的反馈。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯