具有交换功能的Powershell-如何将所有详细输出附加到文件 [英] Powershell with exchange-- How do I append all verbose output to a file

查看:99
本文介绍了具有交换功能的Powershell-如何将所有详细输出附加到文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在脚本中添加一些日志记录.任何建议将不胜感激.首先,我想在出现问题时添加错误日志.

I am trying to add some logging into my script. Any advice would be much appreciated. To start out- I'd like to add an error log when something goes amiss.

例如,当找不到用户时,将引发以下错误:

For instance when a user cannot be found the following error throws:

由于在"HQ-DC-6.domain.com"上找不到对象"asdfa",所以无法执行该操作. + CategoryInfo:未指定:(0:Int32)[Set-RemoteMailbox],ManagementObjectNotFoundException + FullyQualifiedErrorId:47285FC7,Microsoft.Exchange.Management.RecipientTasks.SetRemoteMailbox + PSComputerName:hq-cas2.domain.com

The operation couldn't be performed because object 'asdfa' couldn't be found on 'HQ-DC-6.domain.com'. + CategoryInfo : NotSpecified: (0:Int32) [Set-RemoteMailbox], ManagementObjectNotFoundException + FullyQualifiedErrorId : 47285FC7,Microsoft.Exchange.Management.RecipientTasks.SetRemoteMailbox + PSComputerName : hq-cas2.domain.com

=============================

==============================

$users = ForEach ($user in $(Get-Content 'C:\Users\test\Documents\Powershell Scripts\OffboardUsers.txt')) {

$tmpname = Get-RemoteMailbox -Identity $user | Select-Object -ExpandProperty Name
$tmpDisplayName = Get-RemoteMailbox -Identity $user | Select-Object -ExpandProperty DisplayName

Set-RemoteMailbox -Identity $user -Name ("_" + "$tmpname") >> error.log
Set-RemoteMailbox -Identity $user -DisplayName ("_" + "$tmpDisplayName") >> error.log
Set-RemoteMailbox -Identity $user -HiddenFromAddressListsEnabled $true >> error.log

}

推荐答案

本文于2017年7月18日被完全修订为新的 Write-Log 解决方案,将不会进一步更新.另请参见:从Write-Log迁移.

通常,我发现Microsoft脚本语言的日志记录被低估了.不仅在脚本(或cmdlet)的设计时,日志记录会派上用场,而且在部署脚本时出了点问题,您通常希望您有更好的日志记录.
这就是为什么我认为,像PowerShell这样的脚本语言(及其前身VBScript)实际上应该具有比现在更强大的本机日志记录功能.

In general, I find that logging is underestimated for Microsoft scripting languages. Not only at design time of a script (or cmdlet) logging comes in handy but when the script gets deployed and something goes wrong you often wish that you had much better logging in place.
That's why I think that scripting languages as PowerShell (as well as its predecessor VBScript) should actually come with a more sophisticated native logging capabilities than what is available now.

即使在PowerShell出现之前,我对VBScript中适当的日志记录功能也有类似的需求.实际上,我在VBScript中使用的某些概念仍在PowerShell中使用.同时,我扩展了日志记录解决方案,提供了一系列改进和要求,因为我期望日志功能是:

Even before PowerShell existed, I had a similar need for a adequate logging function in VBScript. As a matter of fact, some of the concepts I was using for VBScript, I am still using in PowerShell. Meanwhile, I have extended my logging solution with a whole list of improvements and requirements as I expect a log function to be:

  • 稳健运行,决不会导致实际的cmdlet意外失败(即使
    当例如出于某种原因拒绝访问日志文件)

  • Robust and never cause the actual cmdlet to fail unexpectedly (even
    when e.g. the access to the log file is for some reason denied)

调用简单,可能用作
Write-Host命令替换

Simple to invoke and possibly be used as a
Write-Host command replacement

解析所有数据类型并显示内容

Resolve all data types and reveal the content

捕获意外的本机脚本错误

Capture unexpected native script errors

能够传递对象以进行内联日志记录,以最大程度地减少其他代码行

Capable to pass-through objects for inline logging to minimize additional code lines

每个条目都有准确的(10ms)时间戳,以解决性能问题
射击

Have an accurate (10ms) timestamp per entry for performance trouble
shooting

标准捕获故障排除信息,例如:

Standard capturing troubleshooting information like:

  • 脚本版本

  • Script version

PowerShell版本

PowerShell version

运行时间(进程开始时间)

When it was ran (process start time)

运行方式(参数)和运行位置(位置)

How (parameters) and from where (location) it was ran

将信息附加到不会无限增长的可配置日志文件中

Appended append information to a configurable log file which doesn't grow indefinitely

向下兼容PowerShell版本2

Downwards compatible with PowerShell version 2

如果您想要一个可靠的日志记录解决方案,则可能希望使用本机的Start-Transcript cmdlet,但是您可能会发现Start-Transcript缺少某些功能,例如时间戳,您可能期望适当的功能.日志记录cmdlet.您可以寻求第三方解决方案,但这通常意味着额外的安装过程和依赖项.
因此,您决定自己编写它,但是即使是仅将信息写入文件的最简单的解决方案,也可能已经在该字段中引起问题:该文件可能无法访问.它甚至可能存在,但是您的脚本被触发了两次,并且多个实例同时运行,一个实例可能打开了日志文件,而另一个实例拒绝了访问(请参见例如:

If you want to go for a robust logging solution, you probably want to go with the native Start-Transcript cmdlet but you will probably find out that the Start-Transcript lacks features, like timestamps, that you might expect from a proper logging cmdlet. You could go for a 3rd party solution but this usually means extra installation procedures and dependencies.
So you decide to write it yourself but even the simplest solution where you just write information to a file might already cause an issue in the field: the file might not be accessible. It might even exist but your script is triggered twice and multiple instances run at the same time the log file might be open by one of instances and access is denied from the other instance (see e.g.: Powershell Scheduled Tasks conflicts?). And just at this point, logging should actually help you to troubleshoot what is going on as a repetitive trigger might also cause unexpected behavior in the script itself. For this particular example, the solution I present here buffers the output until it is able to write. But there are a lot more traps in writing a logging cmdlet and correctly formatting the output.

我已将整个解决方案放入 Log-Entry.ps1框架由几个主要部分组成:

I have put the whole solution in a Log-Entry.ps1 framework consisting out of a few major parts:

  1. 帮助标题-和Main功能模板,其中包含一些示例
  2. 包含某些脚本的My对象-以及日志记录定义
  3. 四个用于控制日志记录的功能:
    • Log-Entry(别名为Log)以记录信息和对象
    • Set-LogFile(别名为LogFile)设置日志文件的位置
    • End-Script(别名为End),可以用来很好地关闭会话
    • ConvertTo-Text(别名为CText)来解析对象
  1. A help header - and a Main function template with a few examples
  2. A My object that contains some script - and logging definitions
  3. Four functions to control the logging:
    • Log-Entry (alias Log) to log information and objects
    • Set-LogFile (alias LogFile) to set the location of the log file
    • End-Script (alias End) which might be used to nicely close the session
    • ConvertTo-Text (alias CText) to resolve objects

有关最新的 Log-Entry.ps1 版本,请参见: https://github.com/iRon7/Log-Entry .

下载上述 Log-Entry.ps1框架并替换示例在Main {}函数中使用您自己的脚本.您想在任何地方显示和记录信息,请使用Log命令(类似于Write-Host命令语法).
运行脚本并在以下位置检查日志文件:%Temp%\<ScriptName>.Log

Download the above Log-Entry.ps1 framwork and replace the examples in the Main {} function with your own script. Everywhere you would like to display and log information, use the Log command (similar to the Write-Host command syntax).
Run the script and check the log file at: %Temp%\<ScriptName>.Log

有关语法的详细信息,请参见: readme.md https://github.com/iRon7/Log-Entry

For details on the syntax, see: the readme.md at https://github.com/iRon7/Log-Entry

示例

以下是一些显示Log-Entry框架功能的命令:

Here are a few commands that show some of the features of the Log-Entry framework:

LogFile .\Test.log                  # Redirect the log file location (Optional)
Log -Color Yellow "Examples:"
Log "Several examples that usually aren't displayed by Write-Host:" $NotSet @() @(@()) @(@(), @()) @($Null)
Log -Indent 1 "Note 1: An empty string:" "" "isn't displayed by Log-Entry either (as you usually do not want every comment quoted)."
Log -Indent 2 "In case you want to reveal a (possible) empty string, use -QuoteString:" -NoNewline; Log -QuoteString ""
Log -Indent 1 "Note 2: An empty array embedded in another array:" @(@()) "is flattened by PowerShell (and not Write-Log)."
Log -Indent 2 "To prevent this use a comma in front of the embbed array: " @(,@())
Log "A hashtable:" @{one = 1; two = 2; three = 3}
Log "A recursive hashtable:" @{one = @{one = @{one = 1; two = 2; three = 3}; two = 2; three = 3}; two = 2; three = 3} -Expand -Depth:9
Log "Character array:" "Hallo World".ToCharArray()
Log-Verbose "The following line produces a error which is captured in the log file:"
$File = Log "File:" (Get-ChildItem "C:\NoSuchFile.txt" -ErrorAction SilentlyContinue)
Log-Verbose "The switch -FlushErrors prevents the error being logged:"
$File = Log "File:" (Get-ChildItem "C:\NoSuchFile.txt" -ErrorAction SilentlyContinue) -FlushErrors
Log "Below are two inline log examples (the object preceding the ""?"" is returned):"
$Height = Log "Height:" 3 ? "Inch"
$Width  = Log "Width:"  4 ? "Inch"
Log-Verbose "Or one display/log line spread over multiple code lines:"
Log "Periphery:" -NoNewline
$Periphery = Log (2 * $Height + 2 * $Width) ? -Color Green -NoNewline
Log "Inch"
Log-Debug "Password:" $Password "(This will not be shown and captured unless the common -Debug argument is supplied)"

显示

示例命令以以下格式显示:

The example commands are displayed in the following format:

日志文件

示例命令在日志文件中记录以下信息:

The example commands record the following information in the log file:

2017-07-13  PowerShell version: 5.1.15063.483, process start: 2017-07-13 15:39:44
15:39:46.75 Log-Entry version: 02.00.01, command line: C:\Users\User\Scripts\Log-Entry\Log-Entry.ps1 
15:39:46.80 Examples:
15:39:46.94 Several examples that usually aren't displayed by Write-Host: $Null @() @() @(@(), @()) @($Null)
15:39:46.95         Note 1: An empty string: isn't displayed by Log-Entry either (as you do not want every comment quoted).
15:39:46.98                 In case you want to reveal a (possible) empty string, use -QuoteString: ""
15:39:47.00         Note 2: An empty array embedded in another array: @() is flattened by PowerShell (and not Write-Log).
15:39:47.01                 To prevent this use a comma in front of the embbed array:  @(@())
15:39:47.05 A hashtable: @{one = 1, three = 3, two = 2}
15:39:47.06 A recursive hashtable: @{
                one = @{
                    one = @{
                        one = 1, 
                        three = 3, 
                        two = 2
                    }, 
                    three = 3, 
                    two = 2
                }, 
                three = 3, 
                two = 2
            }
15:39:47.10 Character array: @(H, a, l, l, o,  , W, o, r, l, d)
15:39:47.11 The following line produces a error which is captured in the log file:
Error at 51,23: Cannot find path 'C:\NoSuchFile.txt' because it does not exist.
15:39:47.15 File: $Null
15:39:47.16 The switch -FlushErrors prevents the error being logged:
15:39:47.17 File: $Null
15:39:47.17 Below are two inline log examples (the object preceding the "?" is returned):
15:39:47.18 Height: 3 Inch
15:39:47.19 Width: 4 Inch
15:39:47.19 Or one display/log line spread over multiple code lines:
15:39:47.20 Periphery: 14 Inch
15:39:47.27 End (Execution time: 00:00:00.5781145, Process time: 00:00:03.1067112)

这篇关于具有交换功能的Powershell-如何将所有详细输出附加到文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆