这应该是一个简单的任务,但我已经看到了几次尝试如何获取执行cmdlet所在目录的路径,并取得了成功.例如,当我执行C:\temp\myscripts\mycmdlet.ps1哪个有设置文件时,C:\temp\myscripts\settings.xml我希望能够存储C:\temp\myscripts在一个变量中mycmdlet.ps1.
这是一个有效的解决方案(虽然有点麻烦):
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'
Run Code Online (Sandbox Code Playgroud)
另一个人建议这个解决方案只适用于我们的测试环境:
$settingspath = '.\settings.xml'
Run Code Online (Sandbox Code Playgroud)
我非常喜欢后一种方法,并且更喜欢每次都必须将文件路径解析为参数,但我不能让它在我的开发环境中工作.有没有人建议做什么?它与PowerShell的配置方式有关吗?
默认情况下,任何具有[CmdletBinding()]属性的命名函数都接受-debug和-verbose(以及其他一些)参数,并具有预定义的$ debug和$ verbose变量.我想弄清楚的是如何将它们传递给在函数内调用的其他cmdlet.
假设我有一个像这样的cmdlet:
function DoStuff() {
[CmdletBinding()]
PROCESS {
new-item Test -type Directory
}
}
Run Code Online (Sandbox Code Playgroud)
if -debug或者-verbose传入我的函数我想将该标志传递给$debugcmdlet.这样做的正确模式是什么?
测试脚本:
function outer
{
[cmdletbinding(supportsshouldprocess=$true)]
param($s)
process
{
$pscmdlet.shouldprocess("outer $s", "ShouldProcess") | out-null
"" | out-file "outer $s"
inner ImplicitPassthru
inner VerbosePassthru -Verbose:$Verbose
inner WhatifPassthru -WhatIf:$WhatIf
}
}
function inner
{
[cmdletbinding(supportsshouldprocess=$true)]
param($s)
process
{
$pscmdlet.shouldprocess("inner $s", "ShouldProcess") | out-null
"" | out-file "inner $s"
}
}
"`n** NORMAL **"
outer normal
"`n** VERBOSE **"
outer verbose -Verbose
"`n** WHATIF **"
outer whatif -WhatIf
Run Code Online (Sandbox Code Playgroud)
输出:
** NORMAL **
VERBOSE: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
What if: Performing operation …Run Code Online (Sandbox Code Playgroud) 我们使用stop-service cmdlet来杀死我们盒子上的一些服务.大部分时间它都很棒,但是我们有一两个服务(谁没有?),偶尔也不会玩得很好.
在这种情况下,其中一个服务将保持停止状态,cmdlet会一遍又一遍地将其输出到控制台:
[08:49:21]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish
[08:49:21]stopping...
[08:49:23]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish
[08:49:23]stopping...
[08:49:25]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish
[08:49:25]stopping...
Run Code Online (Sandbox Code Playgroud)
最终我们必须在任务管理器中终止服务,然后我们的脚本继续.
有没有办法让stop-service cmdlet在某个点之后放弃或超时?我想我们可以在之后检查,如果服务仍然在运行,请使用kill-process cmdlet提供最终的印章.
我有一个自定义的C#PowerShell Cmdlet(继承自Cmdlet基类),我希望能够识别在运行Cmdlet时是否指定了"-Verbose"参数.我意识到当指定-Verbose参数时,WriteVerbose将输出,但是我想在指定-Verbose时实际执行一些其他代码(即,在指定-Verbose时不输出Console.Write值).
谢谢,
约翰
这是我实际代码的简化版本 - 我尽可能小,以便您可以清楚地看到问题:
using System;
using System.Management.Automation;
namespace DemoCmdLet1
{
class Program
{
static void Main(string[] args)
{
var cmd = new GetColorsCommand();
foreach ( var i in cmd.Invoke<string>())
{
Console.WriteLine("- " + i );
}
}
}
[Cmdlet("Get", "Colors")]
public class GetColorsCommand : Cmdlet
{
protected override void ProcessRecord()
{
this.WriteObject("Hello");
this.WriteVerbose("World");
}
}
}
Run Code Online (Sandbox Code Playgroud)以下是基于以下答案的源代码.
有些事情对我来说仍然不清楚:*如何调用"Get-Colors"cmdlet(理想情况下无需将其作为字符串传递给ps对象)*如何获取详细输出,因为它生成而不是获取最后收集它们.
using …Run Code Online (Sandbox Code Playgroud) 所以我有一个名为update-name的cmdlet,我没有权限进行更改.
我创建了一个名为update-name的函数(与cmdlet同名).如何从具有相同名称的函数中调用cmdlet?
我尝试过一些东西,但似乎都没有.
function update-name {
param([string] something)
#call cmdlet update-name here
}
Run Code Online (Sandbox Code Playgroud)
当它只是功能时,有一种方法可以做到:
$unBackup = 'DefaultUpdateName'
if(!(Test-Path Function:\$unBackup)) {
Rename-Item Function:\Update-Name $unBackup
}
function update-name {
& $unName
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果它是CmdLet则不起作用.
我正在尝试从我的C#代码运行PowerShell脚本,它将使用运行它们的程序集中的自定义Cmdlet.这是代码:
using System;
using System.Management.Automation;
[Cmdlet(VerbsCommon.Get,"Hello")]
public class GetHelloCommand:Cmdlet
{
protected override void EndProcessing()
{
WriteObject("Hello",true);
}
}
class MainClass
{
public static void Main(string[] args)
{
PowerShell powerShell=PowerShell.Create();
powerShell.AddCommand("Get-Hello");
foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>())
Console.WriteLine(str);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行它时,我得到一个CommandNotFoundException.我写错了Cmdlet吗?有什么我需要做的事情来在PowerShell或Runspace中注册我的Cmdlet吗?
在C#中,你可以得到当前ParameterSetName的ProcessRecord一个PowerShell的覆盖Cmdlet使用如下代码:
switch (ParameterSetName)
{
case FromUriParamSetName:
loadFromUri();
break;
case FromFileParamSetName:
loadFromFile();
break;
}
Run Code Online (Sandbox Code Playgroud)
我试图找出如何ParameterSetName在脚本cmdlet(高级函数)中获取值.
在Powershell cmdlet中公开一组相关函数时,是否可以共享属性名称和摘要帮助以在程序集中跨cmdlet规范化这些函数?
我知道这可以通过派生类来完成,但是当有多个具有不同属性的cmdlet要共享时,此解决方案最多是尴尬的.
这是一个非常简单的例子.我想分享属性'Name'和所有相关的注释,以便它们在我们生成的N个cmdlet中是相同的,但我想不出在c#中执行此操作的好方法.理想情况下,任何共享都允许指定参数属性,例如Mandatory或Position.
namespace FrozCmdlets
{
using System.Management.Automation;
/// <summary>
/// Adds a new froz to the system.
/// </summary>
[Cmdlet( VerbsCommon.Add, "Froz" )]
public class AddFroz : Cmdlet
{
/// <summary>
/// The name of the froz.
/// For more information on the froz, see froz help manual.
/// </summary>
[Parameter]
public string Name { get; set; }
protected override void ProcessRecord()
{
base.ProcessRecord();
// Add the froz here
}
}
/// <summary>
/// Removes a froz from …Run Code Online (Sandbox Code Playgroud)