[玩转系统] 创建修改系统的 Cmdlet
作者:精品下载站 日期:2024-12-14 02:49:16 浏览:15 分类:玩电脑
创建修改系统的 Cmdlet
有时,cmdlet 必须修改系统的运行状态,而不仅仅是 Windows PowerShell 运行时的状态。在这些情况下,cmdlet 应允许用户有机会确认是否进行更改。
为了支持确认,cmdlet 必须做两件事。
通过将 SupportsShouldProcess 关键字设置为
true
来指定 System.Management.Automation.CmdletAttribute 属性时,声明 cmdlet 支持确认。在执行 cmdlet 期间调用 System.Management.Automation.Cmdlet.ShouldProcess(如以下示例所示)。
通过支持确认,cmdlet 公开 Windows PowerShell 提供的 Confirm
和 WhatIf
参数,并且还满足 cmdlet 的开发指南(有关 cmdlet 开发指南的更多信息,请参阅 Cmdlet 开发指南。)。
改变系统
“更改系统”行为是指可能在 Windows PowerShell 之外更改系统状态的任何 cmdlet。例如,停止进程、启用或禁用用户帐户或向数据库表添加行都是应该确认的系统更改。相反,读取数据或建立瞬时连接的操作不会改变系统,通常不需要确认。对于其效果仅限于 Windows PowerShell 运行时内部的操作(例如 set-variable
),也不需要确认。可能会或可能不会进行持久更改的 Cmdlet 应声明 SupportsShouldProcess
并仅在它们要进行持久更改时才调用 System.Management.Automation.Cmdlet.ShouldProcess。
笔记
ShouldProcess 确认仅适用于 cmdlet。如果命令或脚本通过直接调用 .NET 方法或属性,或者通过调用 Windows PowerShell 外部的应用程序来修改系统的运行状态,则这种形式的确认将不可用。
StopProc Cmdlet
本主题介绍 Stop-Proc cmdlet,该 cmdlet 尝试停止使用 Get-Proc cmdlet 检索的进程(在创建第一个 Cmdlet 中进行了描述)。
定义 Cmdlet
创建 cmdlet 的第一步始终是命名 cmdlet 并声明实现该 cmdlet 的 .NET 类。因为您正在编写一个 cmdlet 来更改系统,所以应该对其进行相应的命名。此 cmdlet 停止系统进程,因此此处选择的动词名称是“Stop”,由 System.Management.Automation.Verbslifecycle 类定义,并使用名词“Proc”指示该 cmdlet 停止进程。有关批准的 cmdlet 动词的详细信息,请参阅 Cmdlet 动词名称。
以下是此 Stop-Proc cmdlet 的类定义。
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
请注意,在 System.Management.Automation.CmdletAttribute 声明中,SupportsShouldProcess
属性关键字设置为 true
以使 cmdlet 能够调用 System.Management.Automation。 Cmdlet.ShouldProcess 和 System.Management.Automation.Cmdlet.ShouldContinue。如果不设置此关键字,用户将无法使用 Confirm
和 WhatIf
参数。
极具破坏性的行为
有些操作具有极大的破坏性,例如重新格式化活动硬盘分区。在这些情况下,cmdlet 在声明 System.Management.Automation.CmdletAttribute 属性时应设置 ConfirmImpact
=ConfirmImpact.High
。即使用户未指定 Confirm
参数,此设置也会强制 cmdlet 请求用户确认。但是,cmdlet 开发人员应避免过度使用 ConfirmImpact
来执行可能具有破坏性的操作,例如删除用户帐户。请记住,如果 ConfirmImpact
设置为 System.Management.Automation.ConfirmImpact 高。
同样,某些操作不太可能具有破坏性,尽管理论上它们确实会修改 Windows PowerShell 之外的系统的运行状态。此类 cmdlet 可以将 ConfirmImpact
设置为 System.Management.Automation.Confirmimpact.Low。这将绕过用户要求仅确认中等影响和高影响操作的确认请求。
定义系统修改参数
本节介绍如何定义 cmdlet 参数,包括支持系统修改所需的参数。如果您需要有关定义参数的一般信息,请参阅添加处理命令行输入的参数。
Stop-Proc cmdlet 定义三个参数:Name
、Force
和 PassThru
。
Name
参数对应于流程输入对象的Name
属性。请注意,此示例中的 Name
参数是必需的,因为如果没有要停止的命名进程,cmdlet 将失败。
Force
参数允许用户覆盖对 System.Management.Automation.Cmdlet.ShouldContinue 的调用。事实上,任何调用 System.Management.Automation.Cmdlet.ShouldContinue 的 cmdlet 都应具有 Force
参数,以便在指定 Force
时,cmdlet 会跳过对 System.out.println() 的调用。 Management.Automation.Cmdlet.ShouldContinue 并继续操作。请注意,这不会影响对 System.Management.Automation.Cmdlet.ShouldProcess 的调用。
PassThru 参数允许用户指示 cmdlet 是否通过管道传递输出对象(在本例中是在进程停止后)。请注意,此参数与 cmdlet 本身相关,而不是与输入对象的属性相关。
以下是 Stop-Proc cmdlet 的参数声明。
[Parameter(
Position = 0,
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
public string[] Name
{
get { return processNames; }
set { processNames = value; }
}
private string[] processNames;
/// <summary>
/// Specify the Force parameter that allows the user to override
/// the ShouldContinue call to force the stop operation. This
/// parameter should always be used with caution.
/// </summary>
[Parameter]
public SwitchParameter Force
{
get { return force; }
set { force = value; }
}
private bool force;
/// <summary>
/// Specify the PassThru parameter that allows the user to specify
/// that the cmdlet should pass the process object down the pipeline
/// after the process has been stopped.
/// </summary>
[Parameter]
public SwitchParameter PassThru
{
get { return passThru; }
set { passThru = value; }
}
private bool passThru;
重写输入处理方法
cmdlet 必须重写输入处理方法。以下代码说明了示例 Stop-Proc cmdlet 中使用的 System.Management.Automation.Cmdlet.ProcessRecord 重写。对于每个请求的进程名称,此方法确保该进程不是特殊进程,尝试停止该进程,然后在指定了 PassThru
参数的情况下发送一个输出对象。
protected override void ProcessRecord()
{
foreach (string name in processNames)
{
// For every process name passed to the cmdlet, get the associated
// process(es). For failures, write a non-terminating error
Process[] processes;
try
{
processes = Process.GetProcessesByName(name);
}
catch (InvalidOperationException ioe)
{
WriteError(new ErrorRecord(ioe,"Unable to access the target process by name",
ErrorCategory.InvalidOperation, name));
continue;
}
// Try to stop the process(es) that have been retrieved for a name
foreach (Process process in processes)
{
string processName;
try
{
processName = process.ProcessName;
}
catch (Win32Exception e)
{
WriteError(new ErrorRecord(e, "ProcessNameNotFound",
ErrorCategory.ReadError, process));
continue;
}
// Call Should Process to confirm the operation first.
// This is always false if WhatIf is set.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
// Call ShouldContinue to make sure the user really does want
// to stop a critical process that could possibly stop the computer.
bool criticalProcess =
criticalProcessNames.Contains(processName.ToLower());
if (criticalProcess &&!force)
{
string message = String.Format
("The process \"{0}\" is a critical process and should not be stopped. Are you sure you wish to stop the process?",
processName);
// It is possible that ProcessRecord is called multiple times
// when the Name parameter receives objects as input from the
// pipeline. So to retain YesToAll and NoToAll input that the
// user may enter across multiple calls to ProcessRecord, this
// information is stored as private members of the cmdlet.
if (!ShouldContinue(message, "Warning!",
ref yesToAll,
ref noToAll))
{
continue;
}
} // if (criticalProcess...
// Stop the named process.
try
{
process.Kill();
}
catch (Exception e)
{
if ((e is Win32Exception) || (e is SystemException) ||
(e is InvalidOperationException))
{
// This process could not be stopped so write
// a non-terminating error.
string message = String.Format("{0} {1} {2}",
"Could not stop process \"", processName,
"\".");
WriteError(new ErrorRecord(e, message,
ErrorCategory.CloseError, process));
continue;
} // if ((e is...
else throw;
} // catch
// If the PassThru parameter argument is
// True, pass the terminated process on.
if (passThru)
{
WriteObject(process);
}
} // foreach (Process...
} // foreach (string...
} // ProcessRecord
调用ShouldProcess方法
在对系统运行状态进行更改(例如删除文件)之前,cmdlet 的输入处理方法应调用 System.Management.Automation.Cmdlet.ShouldProcess 方法来确认操作的执行。这允许 Windows PowerShell 运行时在 shell 中提供正确的“WhatIf”和“Confirm”行为。
笔记
如果 cmdlet 声明它支持 should process,但无法进行 System.Management.Automation.Cmdlet.ShouldProcess 调用,则用户可能会意外修改系统。
对 System.Management.Automation.Cmdlet.ShouldProcess 的调用会将要更改的资源名称发送给用户,Windows PowerShell 运行时会考虑任何命令行设置或首选项变量来确定应向用户显示的内容。
以下示例显示了从示例 Stop-Proc cmdlet 中的 System.Management.Automation.Cmdlet.ProcessRecord 方法的重写中对 System.Management.Automation.Cmdlet.ShouldProcess 的调用。
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
调用ShouldContinue方法
对 System.Management.Automation.Cmdlet.ShouldContinue 方法的调用会向用户发送辅助消息。此调用是在调用 System.Management.Automation.Cmdlet.ShouldProcess 返回 true
且 Force
参数未设置为 true
后进行的。然后用户可以提供反馈以表明是否应该继续操作。您的 cmdlet 调用 System.Management.Automation.Cmdlet.ShouldContinue 作为对潜在危险的系统修改的额外检查,或者当您想要向用户提供“全部是”和“全部否”选项时。
以下示例显示了从示例 Stop-Proc cmdlet 中的 System.Management.Automation.Cmdlet.ProcessRecord 方法的重写中对 System.Management.Automation.Cmdlet.ShouldContinue 的调用。
if (criticalProcess &&!force)
{
string message = String.Format
("The process \"{0}\" is a critical process and should not be stopped. Are you sure you wish to stop the process?",
processName);
// It is possible that ProcessRecord is called multiple times
// when the Name parameter receives objects as input from the
// pipeline. So to retain YesToAll and NoToAll input that the
// user may enter across multiple calls to ProcessRecord, this
// information is stored as private members of the cmdlet.
if (!ShouldContinue(message, "Warning!",
ref yesToAll,
ref noToAll))
{
continue;
}
} // if (criticalProcess...
停止输入处理
进行系统修改的 cmdlet 的输入处理方法必须提供停止输入处理的方法。对于此 Stop-Proc cmdlet,将从 System.Management.Automation.Cmdlet.ProcessRecord 方法调用 System.Diagnostics.Process.Kill* 方法。由于 PassThru
参数设置为 true
,System.Management.Automation.Cmdlet.ProcessRecord 还会调用 System.Management.Automation.Cmdlet.WriteObject 将流程对象发送到管道。
代码示例
有关完整的 C# 示例代码,请参阅 StopProcessSample01 示例。
定义对象类型和格式
Windows PowerShell 使用 .Net 对象在 cmdlet 之间传递信息。因此,小命令可能需要定义其自己的类型,或者小命令可能需要扩展另一个小命令提供的现有类型。有关定义新类型或扩展现有类型的更多信息,请参阅扩展对象类型和格式。
构建 Cmdlet
实施 cmdlet 后,必须通过 Windows PowerShell 管理单元向 Windows PowerShell 注册。有关注册 cmdlet 的详细信息,请参阅如何注册 Cmdlet、提供程序和主机应用程序。
测试 Cmdlet
当您的 cmdlet 已注册到 Windows PowerShell 后,您可以通过在命令行上运行它来测试它。以下是测试 Stop-Proc cmdlet 的几个测试。有关从命令行使用 cmdlet 的详细信息,请参阅 Windows PowerShell 入门。
启动 Windows PowerShell 并使用 Stop-Proc cmdlet 停止处理,如下所示。由于 cmdlet 将
Name
参数指定为强制参数,因此 cmdlet 会查询该参数。PS> stop-proc
将出现以下输出。
Cmdlet stop-proc at command pipeline position 1 Supply values for the following parameters: Name[0]:
现在让我们使用 cmdlet 来停止名为“NOTEPAD”的进程。该 cmdlet 要求您确认该操作。
PS> stop-proc -Name notepad
将出现以下输出。
Confirm Are you sure you want to perform this action? Performing operation "stop-proc" on Target "notepad (4996)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
使用 Stop-Proc 如图所示停止名为“WINLOGON”的关键进程。系统会提示您执行此操作并发出警告,因为这将导致操作系统重新启动。
PS> stop-proc -Name Winlogon
将出现以下输出。
Confirm Are you sure you want to perform this action? Performing operation "stop-proc" on Target "winlogon (656)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y Warning! The process " winlogon " is a critical process and should not be stopped. Are you sure you wish to stop the process? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): N
现在让我们尝试停止 WINLOGON 进程而不收到警告。请注意,此命令条目使用
Force
参数来覆盖警告。PS> stop-proc -Name winlogon -Force
将出现以下输出。
Confirm Are you sure you want to perform this action? Performing operation "stop-proc" on Target "winlogon (656)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): N
参见
添加处理命令行输入的参数
扩展对象类型和格式
如何注册 Cmdlet、提供程序和主机应用程序
Windows PowerShell SDK
Cmdlet 示例
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag