gpt4 book ai didi

powershell - 如果抛出错误,我如何继续处理项目?

转载 作者:行者123 更新时间:2023-12-03 00:37:08 33 4
gpt4 key购买 nike

不得不用实际代码重写这篇文章,因为二进制模块肯定存在某种差异。

完整的 cmdlet 如下(见长见谅):

简而言之,此函数基本上使用 SMO 库并从 SQL Server 实例中提取有关数据库用户的信息。

namespace Namespace
{
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Collections.Generic;
using System.Management.Automation;

using static PrivateFunctions;

[Cmdlet(VerbsCommon.Get, "DatabaseUserInformation")]
public class GetDatabaseUserInformationCmdlet : PSCmdlet
{
[Parameter(Mandatory = true,
HelpMessage = "The user name of the account to retrieve information for.",
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
public string LogonName { get; set; }

private List<object> userInformation = new List<object>();

protected override void ProcessRecord()
{
string samAccountName = GetSamAccountName(LogonName);
Login login = null;
User user = null;

WriteVerbose($"Getting login for account: {samAccountName}...");
try
{
login = GetLogin(samAccountName);
}
catch (InvalidOperationException invalidOperation)
{
ThrowTerminatingError(new ErrorRecord(
invalidOperation,
"LoginNotFound",
ErrorCategory.InvalidOperation,
login));

}

WriteVerbose($"Getting user for login: {login.Name}...");
try
{
user = GetUser(login);
}
catch (InvalidOperationException invalidOperation)
{
ThrowTerminatingError(new ErrorRecord(
invalidOperation,
"UserNotFound",
ErrorCategory.InvalidOperation,
user));
}

WriteVerbose($"Gathering information for user: {user.Name}");
var information = new
{
LoginName = login.Name,
UserName = user.Name,
FullAccess = TestFullAccessOnDatabase(user),
Roles = user.EnumRoles()
};

userInformation.Add(information);

}

protected override void EndProcessing()
{
WriteVerbose("Writing information to output.");
userInformation.ForEach(item => WriteObject(item));
}
}
}

cmdlet 可以与单个参数一起使用:
Get-DatabaseUserInformation user1

或者我还希望能够在与多个用户打交道时将数组传递给它。
@('user1', 'user2','user3') | Get-DatabaseUserInformation

如果我使用的是单个值并且该用户不存在,那么公平地说,它会终止,这是一个更正并再次运行它的情况。

但是当我将它与多个值一起使用时,如果其中一个值不存在,它不会给出任何输出,只有异常(exception)。

所以当一切正常时我得到的输出是这样的(详细打开):
VERBOSE: Getting login for account: DOMAIN\user1...
VERBOSE: Getting user for login: DOMAIN\user1...
VERBOSE: Gathering information for user: dbo
VERBOSE: Getting login for account: DOMAIN\user2...
VERBOSE: Getting user for login: DOMAIN\user2...
VERBOSE: Gathering information for user: user2
VERBOSE: Getting login for account: DOMAIN\user3...
VERBOSE: Getting user for login: DOMAIN\user3...
VERBOSE: Gathering information for user: user3
VERBOSE: Writing information to output.

LoginName UserName FullAccess Roles
--------- -------- ---------- -----
DOMAIN\user1 dbo True {db_owner}
DOMAIN\user2 user2 False {role1}
DOMAIN\user3 user3 False {}

当出现问题时我会得到什么:(在这种情况下,user2 拼写错误。)
Get-DatabaseUserInformation : A login for the account 'DOMAIN\usr2' does not
exist in the database.
At line:1 char:6
+ $x | Get-DatabaseUserInformation -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-DatabaseUserInformation], InvalidOperationException
+ FullyQualifiedErrorId : LoginNotFound,DatabaseUserManagement.GetDatabase
UserInformationCmdlet

我想要发生的事情与此类似。
VERBOSE: Getting login for account: DOMAIN\user1...
VERBOSE: Getting user for login: DOMAIN\user1...
VERBOSE: Gathering information for user: dbo
VERBOSE: Getting login for account: DOMAIN\usr2...
Get-DatabaseUserInformation : A login for the account 'DOMAIN\usr2' does not
exist in the database.
At line:1 char:6
+ $x | Get-DatabaseUserInformation -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-DatabaseUserInformation], InvalidOperationException
+ FullyQualifiedErrorId : LoginNotFound,DatabaseUserManagement.GetDatabase
UserInformationCmdlet
VERBOSE: Getting login for account: DOMAIN\user3...
VERBOSE: Getting user for login: DOMAIN\user3...
VERBOSE: Gathering information for user: user3
VERBOSE: Writing information to output.

LoginName UserName FullAccess Roles
--------- -------- ---------- -----
DOMAIN\user1 dbo True {db_owner}
DOMAIN\user3 user3 False {}

最佳答案

编辑:问题显然出在 ThrowTerminating 错误中。在此处阅读 msdn 说明:

https://msdn.microsoft.com/en-us/library/system.management.automation.cmdlet.throwterminatingerror(v=vs.85).aspx

备注 部分指出,如果要继续处理管道,则不应使用此方法:

When a cmdlet encounters a terminating error, call this method rather than simply throwing an exception. Calling this method allows the cmdlet to attach additional error record information that describes the condition that caused the terminating error. When this method is called, the Windows PowerShell runtime catches the error record and then starts shutting down the pipeline. For more information about error reporting and error records, see Windows PowerShell Error Reporting. This method should not be used when errors occur where the cmdlet can continue processing records. To send error reports when nonterminating errors occur, call the WriteError method. For more information about cmdlets, see Windows PowerShell Cmdlets.



你必须编写一个像这样的高级函数:
Function Get-StringLength()
{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline=$true)]
$value
)
Begin {}
Process {
Write-Output $value.Length
}
End {}
}

Begin block 是你准备东西的地方,Process block 是你处理管道中每个对象的地方,这意味着它是为管道中的每个对象运行的。你清理结束 block 中的烂摊子。

因为它是一个 cmdlet,所以您可以使用 ErrorAction 来控制发生错误时发生的情况:
$values | Get-StringLength -ErrorAction SilentlyContinue

您甚至可以使用以下方法将这些错误放入变量中:
$values | Get-StringLength -ErrorAction SilentlyContinue -ErrorVariable MyErrors

关于powershell - 如果抛出错误,我如何继续处理项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33041405/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com