How to create a dynamic variable in Powershell, sucha as date/time etc

后端 未结 5 916
太阳男子
太阳男子 2020-12-22 08:20

Hi i am not exactly sure if my wording is right but i need a variable which contains current date/time whenever i write data to log ; how can i do that with

相关标签:
5条回答
  • 2020-12-22 08:38

    This script make the real Dynamic variable in Powershell ( Thanks to Lee Holmes and his 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))
    

    There's a Set-StrictMode -Version 3 but you can set it as -Version 2 if you can load framework 4.0 in your powershell V2.0 session as explained Here

    The use for the OP is:

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

    Here the Lee Holmes's evaluation (where it is clear what is the real flaw) about the method I used in my other answer:

    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.
    
    0 讨论(0)
  • 2020-12-22 08:38

    Using PsBreakPoint:

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

    calling $now returns current updated datetime value

    One liner:

    $now = Set-PSBreakpoint -Variable now -Mode Read -Action { $global:now = (get-date).datetime }
    
    0 讨论(0)
  • 2020-12-22 08:40

    Why not use:

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

    This gets the current datetime every time. Notice that it's inside $( ) which makes powershell run the expression(get the datetime) before inserting it into the string.

    0 讨论(0)
  • 2020-12-22 08:41

    Besides these other ways (which frankly I would probably use instead - except the breakpoint approach), you can create a custom object with a ScriptProperty that you can provide the implementation for:

    $obj = new-object pscustomobject
    $obj | Add-Member ScriptProperty Now -Value { Get-Date }
    $obj.now
    
    0 讨论(0)
  • 2020-12-22 08:42

    wrap your two commands in function so you will have just one call ?

    function add-log{
    (param $txt)
    $DateTime = get-date  | select -expand datetime
    Add-Content $LogFile -Value "$DateTime: $txt"
    }
    
    0 讨论(0)
提交回复
热议问题