0

嗨,我不确定我的措辞是否正确,但每当我将数据写入日志时,我都需要一个包含当前日期/时间的变量;如果不每次都初始化,我怎么能做到这一点。目前每次我需要更新时,我都会联合使用这两个语句。还有其他方法吗?

$DateTime = get-date  | select datetime
Add-Content $LogFile -Value "$DateTime.DateTime: XXXXX"

如果对我的问题有任何疑问或澄清,请告诉我。

4

5 回答 5

4

此脚本在 Powershell 中生成真正的动态变量(感谢Lee Holmes和他的Windows PowerShell Cookbook The Complete Guide to Scripting Microsoft's Command Shell, 3rd Edition

##############################################################################
##
## New-DynamicVariable
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Creates a variable that supports scripted actions for its getter and setter

.EXAMPLE

PS > .\New-DynamicVariable GLOBAL:WindowTitle `
     -Getter { $host.UI.RawUI.WindowTitle } `
     -Setter { $host.UI.RawUI.WindowTitle = $args[0] }

PS > $windowTitle
Administrator: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
PS > $windowTitle = "Test"
PS > $windowTitle
Test

#>

param(
    ## The name for the dynamic variable
    [Parameter(Mandatory = $true)]
    $Name,

    ## The scriptblock to invoke when getting the value of the variable
    [Parameter(Mandatory = $true)]
    [ScriptBlock] $Getter,

    ## The scriptblock to invoke when setting the value of the variable
    [ScriptBlock] $Setter
)

Set-StrictMode -Version 3

Add-Type @"
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;

namespace Lee.Holmes
{
    public class DynamicVariable : PSVariable
    {
        public DynamicVariable(
            string name,
            ScriptBlock scriptGetter,
            ScriptBlock scriptSetter)
                : base(name, null, ScopedItemOptions.AllScope)
        {
            getter = scriptGetter;
            setter = scriptSetter;
        }
        private ScriptBlock getter;
        private ScriptBlock setter;

        public override object Value
        {
            get
            {
                if(getter != null)
                {
                    Collection<PSObject> results = getter.Invoke();
                    if(results.Count == 1)
                    {
                        return results[0];
                    }
                    else
                    {
                        PSObject[] returnResults =
                            new PSObject[results.Count];
                        results.CopyTo(returnResults, 0);
                        return returnResults;
                    }
                }
                else { return null; }
            }
            set
            {
                if(setter != null) { setter.Invoke(value); }
            }
        }
    }
}
"@

## If we've already defined the variable, remove it.
if(Test-Path variable:\$name)
{
    Remove-Item variable:\$name -Force
}

## Set the new variable, along with its getter and setter.
$executioncontext.SessionState.PSVariable.Set(
    (New-Object Lee.Holmes.DynamicVariable $name,$getter,$setter))

有一个Set-StrictMode -Version 3,但如果您可以在 powershell V2.0 会话中加载框架 4.0,则可以将其设置为 -Version 2,如下所述

OP的用途是:

 New-DynamicVariable -Name GLOBAL:now -Getter { (get-date).datetime }

这里是 Lee Holmes 对我在另一个答案中使用的方法的评估(很明显真正的缺陷是什么):

Note
There are innovative solutions on the Internet that use PowerShell's debugging facilities to create a breakpoint that changes a variable's value whenever you attempt to read from it. While unique, this solution causes PowerShell to think that any scripts that rely on the variable are in debugging mode. This, unfortunately, prevents PowerShell from enabling some important performance optimizations in those scripts.
于 2013-01-24T14:13:17.440 回答
3

为什么不使用:

Add-Content $LogFile -Value "$((Get-Date).DateTime): XXXXX"

这每次都会获取当前的日期时间。请注意,它在内部$( )使 powershell 在将其插入字符串之前运行表达式(获取日期时间)。

于 2013-01-23T14:45:50.420 回答
2

将你的两个命令包装在函数中,这样你就只有一个调用?

function add-log{
(param $txt)
$DateTime = get-date  | select -expand datetime
Add-Content $LogFile -Value "$DateTime: $txt"
}
于 2013-01-23T14:45:40.527 回答
1

除了这些其他方式(坦率地说,我可能会改用这些方式 - 除了断点方法),您可以创建一个带有 ScriptProperty 的自定义对象,您可以提供以下实现:

$obj = new-object pscustomobject
$obj | Add-Member ScriptProperty Now -Value { Get-Date }
$obj.now
于 2013-01-23T14:45:47.913 回答
1

使用PsBreakPoint

$act= @'
$global:now = (get-date).datetime
'@
$global:sb = [scriptblock]::Create($act)
$now = Set-PSBreakpoint -Variable now -Mode Read -Action $global:sb

调用$now返回当前更新的日期时间值

一个班轮:

$now = Set-PSBreakpoint -Variable now -Mode Read -Action { $global:now = (get-date).datetime }
于 2013-01-23T14:59:25.817 回答