Powershell 脚本 - 脚本 - 如何禁用它

Powershell script - Transcript - How I disable it

提问人:David Nový 提问时间:9/15/2023 最后编辑:mklement0David Nový 更新时间:9/19/2023 访问量:240

问:

我有powershell脚本。在调度程序上,我运行运行 PS1 文件的 bat 文件。

BAT 文件

Powershell.exe -executionpolicy remotesigned -File script.PS1

PS1 文件

$path = "D:\data";
$limit = (Get-Date).AddHours(-3);
Get-ChildItem -Path $path -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force;

在同一目录中,powershell 以 YYYYMMDD 格式创建包含文件PowerShell_transcript的目录。SERVER.t7eh07Gy.20230914031500.txt。下面是整个脚本运行。

例如: D:\data\20230914\PowerShell_transcript。SERVER.t7eh07Gy.20230914031500.txt D:\data\20230915\PowerShell_transcript。SERVER.t7eh07Gy.20230914031500.txt 等。

如何禁用它?

我试过停止转录等。

我需要停止成绩单。

PowerShell 组策略 听录

评论

1赞 Re1ter 9/15/2023
听录的开始可以由组策略确定,并独立于脚本执行。在此处检查策略,例如:“HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription”
0赞 David Nový 9/15/2023
这里是 EnableTranscripting=1
2赞 Re1ter 9/15/2023
这表示系统管理员已配置所有脚本的自动转录。
0赞 David Nový 9/15/2023
我已将其更改为 EnableTranscripting=0。看起来不错。
2赞 David Nový 9/15/2023
重新启动后会恢复旧值。我必须与管理员一起解决它。谢谢。

答:

4赞 Re1ter 9/15/2023 #1

听录的开始可以由组策略确定,并独立于脚本执行。在此处查看策略示例:

HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription

如果此键中有一个 EnableTranscripting 值,并且它不等于零,则启用听录。

评论

0赞 lit 9/16/2023
这会起作用吗??如果该值不存在,它将返回 $null。Get-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -Name EnableTranscripting
0赞 mklement0 9/17/2023
@lit,是的,如果你添加.也可以用于仅返回值(数据)。鉴于也可以使用用户 (HKCU) GPO 启用转录,因此必须检查两个位置(如果在两个位置中都定义,则 HKLM 策略优先): 因此,请先检查,然后再检查-ErrorAction IgnoreGet-ItemPropertyValueGet-ItemPropertyValue -ErrorAction Ignore -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -Name EnableTranscriptingGet-ItemPropertyValue -ErrorAction Ignore -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -Name EnableTranscripting
1赞 mklement0 9/19/2023 #2

Re1ter 的有用回答提供了关键的指针;让我补充一些背景信息

  • 你所看到的是已启用的 GPO(组策略 [对象])的效果,这会导致所有 PowerShell 会话(无论是否交互式)的自动听录,就像在每个会话的开始和结束时调用了 Start-Transcript 和 Stop-Transcript 一样。Turn on PowerShell Transcription

  • 如果启用此策略:

    • 成绩单使用名称格式存储在特定于日历日的目录中,例如 于 2023 年 9 月 18 日,在使用 name 格式的文件中,其中组件按顺序表示以下内容:yyyMMdd20230918PowerShell_transcript.*.*.*.txt*

      • 计算机名称(例如server1)
      • 由 8 个字母数字字符组成的随机字符串(例如IjrFVsl1)
      • 可排序的本地时间戳;相当于会话开始时的(例如,'')[datetime]::Now.ToString('s') -replace '\D'
      • 例:
        • PowerShell_transcript.server1.IjrFVsl1.20230918162121.txt
    • 默认情况下,特定于日历日的目录存储在用户的目录中(通常为 ;determine with ),但位置是可配置的。Documents$HOME\Documents[System.Environment]::GetFolderPath('MyDocuments')

  • 策略设置存储在注册表中,可以在其中查询它们,但不应在那里修改它们(从技术上讲,您只能以管理员身份进行修改):注册表修改不会与原始 GPO 同步,在域环境中,甚至可能在每次重新启动/登录时被覆盖。

    • 相反,应通过 GUI 或 GroupPolicy PowerShell 模块中的 cmdlet 来管理策略。gpedit.msc
  • 该策略可以在计算机级别定义,存储在 () 注册表配置单元中,也可以在用户级别定义,存储在每个用户的 () 注册表配置单元中。HKEY_LOCAL_MACHINEHKLM:HKEY_CURRENT_USERHKCU:

    • 如果在两个级别都定义了策略(这没有意义),则计算机级别的策略优先。
  • PowerShell (Core) 7+ 具有 Windows PowerShell 不同的策略,但可以将其配置为委托给后者的策略。


以下 Get-AutomaticTranscriptionSettings 便利函数 (底部的源代码) 直接查询注册表以报告有效的策略设置,因此不需要该模块,该模块需要安装 RSAT 工具。GroupPolicy

调用示例:

PS> Get-AutomaticTranscriptionSettings

Enabled                     : True
OutputPathPattern           : C:\Users\jdoe\Documents\2*\PowerShell_transcript.*.*.*.txt
IncludeInvocationHeaders    : False
PSEdition                   : Core
UsesWindowsPowerShellPolicy : True
GPOScope                    : Machine
RegistryKey                 : {HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PowerShellCore\Transcription, HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription}

上面显示了在计算机级别启用的 PowerShell (Core) 策略,该策略委托给 Windows PowerShell 策略(在同一级别)

请注意,属性值可以直接传递到以列出所有现有脚本。OutputPathPatternGet-ChildItem


Get-AutomaticTranscriptionSettings 源代码

function Get-AutomaticTranscriptionSettings {
  <#
.SYNOPSIS
  Reports the current automatic transcription settings for PowerShell, if any.
.DESCRIPTION
  Targets the edition that is running the script by default, but you change
  that with -Edition, which accepts 'Core' or 'Desktop' (Windows PowerShell)

  If transcribing is enabled, the .OutputPathPattern property of the output 
  object can be passed to Get-ChildItem -Path to find all current transcripts.

  Note that transcripts are stored in calendar-day-specific subfolders using the
  "yyyDDmm" format, with the transcripts file names matching pattern
  "PowerShell_transcript.*.*.*.txt"
#>

  [CmdletBinding()]
  param(
    [ValidateSet('Core', 'Desktop')]
    [Alias('PSEdition')]
    [string] $Edition
  )

  if ($env:OS -ne 'Windows_NT') { throw 'This command runs on Window only.' }

  Set-StrictMode -Version 1

  if (-not $Edition) {
    # Default to the running edition.
    $Edition = ('Desktop', 'Core')[$PSVersionTable.PSEdition -eq 'Core']
  }
  # Normalize the casing
  $Edition = [char]::ToUpperInvariant($Edition[0]) + $Edition.Substring(1).ToLowerInvariant()

  $regKeys = [ordered] @{
    Desktop = [ordered] @{
      HKLM = Get-Item -ErrorAction Ignore -LiteralPath 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription'
      HKCU = Get-Item -ErrorAction Ignore -LiteralPath 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription'
    }
    Core    = [ordered] @{
      HKLM = Get-Item -ErrorAction Ignore -LiteralPath 'HKLM:\SOFTWARE\Policies\Microsoft\PowerShellCore\Transcription'
      HKCU = Get-Item -ErrorAction Ignore -LiteralPath 'HKCU:\SOFTWARE\Policies\Microsoft\PowerShellCore\Transcription'
    }    
  }

  $effectiveValue = $null # The *absence* of the value is the same as 0
  $effectiveKey = $originalKey = $null
  $usesWinPSPolicy = $false
  foreach ($hive in 'HKLM', 'HKCU') {
    if ($null -ne ($key = $regKeys.$Edition.$hive) -and $null -ne ($value = $key.GetValue('EnableTranscripting'))) {
      if ($Edition -eq 'Core' -and 1 -eq $key.GetValue('UseWindowsPowerShellPolicySetting')) {        
        $usesWinPSPolicy = $true
        $originalKey = $key
        # Use the WinPS settings in the *same hive*
        $key = $regKeys.Desktop.$hive
        $value = if ($null -ne $key) { $key.GetValue('EnableTranscripting') }
      }
      $effectiveKey = $key
      $effectiveValue = $value
      break
    }
  }

  # Construct the output object.
  # Note that the `$(...)` enclosure around the `if` statement is needed for WinPS-compatibility.
  [pscustomobject] @{      
    Enabled                     = 1 -eq $effectiveValue # only 1, specifically, is recognized as the enabling number.
    OutputPathPattern           = $(if ($effectiveKey) { 
        $dir = $effectiveKey.GetValue('OutputDirectory')
        if (-not $dir) { $dir = [System.Environment]::GetFolderPath('MyDocuments') }
        # Output dirs are calendar-day specific "yyyyMMdd" dirs., inside of which each session
        # is transcribed in a "PowerShell_transcript.*.*.*.txt" file.
        Join-Path $dir 2*\PowerShell_transcript.*.*.*.txt
      })
    IncludeInvocationHeaders    = $(if ($effectiveKey) { 1 -eq $effectiveKey.GetValue('EnableInvocationHeader') })
    PSEdition                   = $Edition
    UsesWindowsPowerShellPolicy = $(if ($null -ne $effectiveValue) { if ($Edition -eq 'Desktop') { $true } else { $usesWinPSPolicy } })
    GPOScope                    = $(if ($effectiveKey) { ('User', 'Machine')[$effectiveKey -like 'HKEY_LOCAL_MACHINE\*'] })
    RegistryKey                 = $(if ($usesWinPSPolicy -and $originalKey) { $originalKey.ToString() } if ($effectiveKey) { $effectiveKey.ToString() })
  }

}