Глава 2. Даты и журналы

Для создания сценариев существенно понимать как мы пользуемся командлетами даты и времени для временных отметок различного типа операций, например, для создания файла журнала с отметкой времени. Я поделюсь функцией шпаргалки, которую вы сможете применять внутри своих сценариев для создания журналов с отметкой времени, а также записей с временной отметкой внутри своего сценария.

Давайте пройдёмся по некоторым иллюстрациям даты и времени прежде чем применять свою функцию Write-Log, которую я уже создал для вас. (Это самый первый реальный код шпаргалки, которым вы можете пользоваться в своих сценариях!)

Команда get-date снабжает вас значениями текущих даты и времени, как это показано на Рисунке 2-1.

 

Рисунок 2-1


Отображение командлета get-date

Для форматирования его таким образом, чтобы они позволяли нам применять их в названиях файлов и прочих экземплярах, может применяться команда format, как это показано на Рисунке 2-2.


get-date -format d
		
 

Рисунок 2-2


Отображение отформатированной даты

Листинг 2-1 показывает применение в имени файла даты и времени.

 

Листинг 2-1. Код для использования даты и времени в имени файла


$date = get-date -format d                  # форматирование
$date = $date.ToString().Replace("/", "-")  # замена / на -
$time = get-date -format t    # only show time
$time = $time.ToString().Replace(":", "-") # замена : на -
$time = $time.ToString().Replace(" ", "")

$m = get-date
$month = $m.month  #получение месяца
$year = $m.year    #получение года
 	   

Примеры:- (теперь склеиваем всё это воедино)


#на основе даты
$log1 = ".\Processed\Logs" + "\" + "skipcsv_" + $date + "_.log"

#на основе месяца и года
$log2 = ".\Processed\Logs" + "\" + "Created_" + $month +"_" + $year +"_.log"

#на основе даты и времени
$output1 = ".\" + "G_Testlog_" + $date + "_" + $time + "_.csv"
 	   
[Замечание]Замечание

Всегда определяйте свою текущую рабочую папку.

Манипуляция датами

Вы видели что get-date способна снабдить вас значениями текущих даты и времени. Вы можете манипулировать ими в соответствии с имеющимися потребностями своего решения написания сценария. Здесь я кратко продемонстрирую как выполнять такие операции как получение первого и последнего дней месяца и получения отметки времени и даты полуночи.

Для получения первого и последнего дней месяца мы можем воспользоваться своим кодом из Листинга 2-2. За результатами обращайтесь к Рисунку 2-3.

 

Листинг 2-2. Код для извлечения первого и последнего дней месяца


$date= Get-Date -Day 01
$lastday = ((Get-Date -day 01).AddMonths(1)).AddDays(-1)

$start = $date
$end  = $lastday
 	   
 

Рисунок 2-4


Получение первого и последнего дней соответствующего месяца

Для получения штампа полуночи просто воспользуйтесь этой строкой кода (и посмотрите на Рисунок 2-4):


Get-Date -Hour 0 -Minute 0 -Second 0
		
 

Рисунок 2-4


Отображение того как получать отметку даты и времени полуночи

Создание папок на основе даты

В реальной жизни могут иметься случаи, при которых вы пожелаете создавать папки на основе текущей даты, например для создания ежедневной резервной копии конфигурации SharePoint и помещения её в папке с отметкой даты. Листинг 2-3 отображает тот код, которым можно воспользоваться для выполнения такой задачи, а Рисунок 2-5 отображает получаемые результаты.

 

Листинг 2-3. Код для создания структуры папок на основе даты


$Dname = ((get-date).AddDays(0).toString('yyyyMMdd')) #манипуляция с датой
$dirName = "ConfigBackup_$Dname"  #префикс для соответствующей папки

New-Item -Path c:\temp -Name $dirName -ItemType directory
 	   
 

Рисунок 2-5


Создание структуры папок на основе даты

Готовые функции даты и журнала

Здесь три готовых функции, которые вы можете копировать и вставлять внутри своих сценариев по мере своих потребностей. Ближе к концу этой книги я продемонстрирую как создавать сценарий целиком при помощи готовых к применению функций или совместного кода из этой книги.

Функция Write-Log: Она пользуется другой функцией с названием New-FolderCreation, которую, если потребуется, можно применять отдельно. Просмотрите Листинг 2-4.

 

Листинг 2-4. Код функции Write-Log


function New-FolderCreation
{
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $true)]
    [string]$foldername
  )
  $logpath  = (Get-Location).path + "\" + "$foldername"
  $testlogpath = Test-Path -Path $logpath
  if($testlogpath -eq $false)
  {
    #Start-ProgressBar -Title "Creating $foldername folder" -Timer 10
    $null = New-Item -Path (Get-Location).path -Name $foldername -Type directory
  }
}#New-FolderCreation

function Write-Log
{
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $true,ParameterSetName = 'Create')]
    [array]$Name,
    [Parameter(Mandatory = $true,ParameterSetName = 'Create')]
    [string]$Ext,
    [Parameter(Mandatory = $true,ParameterSetName = 'Create')]
    [string]$folder,
    [Parameter(ParameterSetName = 'Create',Position = 0)][switch]$Create,
    [Parameter(Mandatory = $true,ParameterSetName = 'Message')]
    [String]$message,
    [Parameter(Mandatory = $true,ParameterSetName = 'Message')]
    [String]$path,
    [Parameter(Mandatory = $false,ParameterSetName = 'Message')]
    [ValidateSet('Information','Warning','Error')]
    [string]$Severity = 'Information',
    [Parameter(ParameterSetName = 'Message',Position = 0)][Switch]$MSG
  )
  switch ($PsCmdlet.ParameterSetName) {
    "Create"
    {
      $log = @()
      $date1 = Get-Date -Format d
      $date1 = $date1.ToString().Replace("/", "-")
      $time = Get-Date -Format t
      $time = $time.ToString().Replace(":", "-")
      $time = $time.ToString().Replace(" ", "")
      New-FolderCreation -foldername $folder
      foreach ($n in $Name)
      {$log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext"}
      return $log
    }
    "Message"
    {
      $date = Get-Date
      $concatmessage = "|$date" + "|   |" + $message +"|  |" + "$Severity|"
      switch($Severity){
        "Information"{Write-Host -Object $concatmessage -ForegroundColor Green}
        "Warning"{Write-Host -Object $concatmessage -ForegroundColor Yellow}
        "Error"{Write-Host -Object $concatmessage -ForegroundColor Red}
      }
      Add-Content -Path $path -Value $concatmessage
    }
  }
} #Function Write-Log
 	   

Для создания файла журнала вы можете просто воспользоваться тем как это показано ниже (это автоматически создаст необходимые папки):


$log = Write-Log -Name "Name-Log" -folder "logs" -Ext "log"
		

Для создания файла CSV с целью отчётов вы можете применять его так:


$Report1 = Write-Log -Name "MAM-Report" -folder "Report" -Ext "csv"
		

Для записи сведений в файл журнала вы можете применить это:


Write-log -Message "Connect to Intune" -path $log
		

Для записи предостережений в файл журнала можно применять следующее:


Write-log -Message "Connect to Intune" -path $log -Severity Warning
		

Для записи ошибки в файл журнала вы можете воспользоваться этим:


Write-Log -Message "Error loading Modules" -path $log -Severity Error
		

Рисунок 2-6 показывает работу Write-Log в консоли PowerShell.

 

Рисунок 2-6


Операция Write-Log

Необходимый файл журнала создаётся в папке logs и будет создавать структурированный текстовый журнал, как это показано на Рисунке 2-7.

 

Рисунок 2-7


Созданный после применения функции Write-Log файл журнала

Функция Set-Recyclelogs: Будет удалять соответствующие файлы на основании числа дней в качестве входных данных. По мере накопления журналов со временем, имеется потребность для их отработки после определённого периода времени во избежание переполнения накопителей сервера. Это важно для любых сценариев, которым вы разрешили журналирование. Воспользуйтесь кодом из Листинга 2-5.

 

Листинг 2-5. Код для функции Set-Recyclelogs


function Set-Recyclelogs
{
  [CmdletBinding(
      SupportsShouldProcess = $true,
  ConfirmImpact = 'High')]
  param
  (
    [Parameter(Mandatory = $true,ParameterSetName = 'Local')]
    [string]$foldername,
    [Parameter(Mandatory = $true,ParameterSetName = 'Local')]
    [Parameter(Mandatory = $true,ParameterSetName = 'Path')]
    [Parameter(Mandatory = $true,ParameterSetName = 'Remote')]
    [int]$limit,

    [Parameter(ParameterSetName = 'Local',Position = 0)][switch]$local,

    [Parameter(Mandatory = $true,ParameterSetName = 'Remote')]
    [string]$ComputerName,
    [Parameter(Mandatory = $true,ParameterSetName = 'Remote')]
    [string]$DriveName,
    [Parameter(Mandatory = $true,ParameterSetName = 'Remote')]
    [string]$folderpath,

    [Parameter(ParameterSetName = 'Remote',Position = 0)][switch]$Remote,

    [Parameter(Mandatory = $true,ParameterSetName = 'Path')]
    [ValidateScript({
          if(-Not ($_ | Test-Path) ){throw "File or folder does not exist"}
          return $true
    })]
    [string]$folderlocation,

    [Parameter(ParameterSetName = 'Path',Position = 0)][switch]$Path

  )

  switch ($PsCmdlet.ParameterSetName) {
    "Local"
    {
      $path1 = (Get-Location).path + "\" + "$foldername"
      if ($PsCmdlet.ShouldProcess($path1 , "Delete"))
      {
        Write-Host "Path Recycle - $path1 Limit - $limit" -ForegroundColor Green
        $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling
        $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1}
        ForEach($item in $getitems){
          Write-Verbose -Message "Deleting item $($item.FullName)"
          Remove-Item $item.FullName -Force
        }
      }
    }

    "Remote"
    {
      $path1 = "\\" + $ComputerName + "\" + $DriveName + "$" + "\" + $folderpath
      if ($PsCmdlet.ShouldProcess($path1 , "Delete"))
      {
        Write-Host "Recycle Path - $path1 Limit - $limit" -ForegroundColor Green
        $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling
        $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1}
        ForEach($item in $getitems){
          Write-Verbose -Message "Deleting item $($item.FullName)"
          Remove-Item $item.FullName -Force
        }
      }
    }

   "Path"
    {
      $path1 = $folderlocation
      if ($PsCmdlet.ShouldProcess($path1 , "Delete"))
      {
        Write-Host "Path Recycle - $path1 Limit - $limit" -ForegroundColor Green
        $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling
        $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1}
        ForEach($item in $getitems){
          Write-Verbose -Message "Deleting item $($item.FullName)"
          Remove-Item $item.FullName -Force
        }
      }
    }
  }
}# Set-Recycle logs
 	   

Для отработки журналов старше 10 дней внутри вашей папки logs в текущем каталоге:


Set-Recyclelogs -foldername logs -limit 10
		

Воспользуйтесь confirm:$false во избежание подтверждений если вы уверены что вы хотите удалить эти файлы:


Set-Recyclelogs -foldername logs -limit 10 -confirm:$false
		

Для проверки того какие файлы удаляются применяйте verbose:


Set-Recyclelogs -foldername logs -limit 10 -confirm:$false -verbose
		

Когда ваш сценарий в другом каталоге, а вы хотите удалять журналы в иной структуре папок, вы можете задать значение пути:


Set-Recyclelogs -foldername logs -limit 10 -confirm:$false -verbose
		

Для отработки журналов в удалённой машине воспользуйтесь следующим синтаксисом:


Set-Recyclelogs -ComputerName testmachine -DriveName c -folderpath data\logs -limit 10
		

Функция Set-ProgressBar: Эта функция просто отображает планку исполнения, когда ы желаете установить паузу на некоторое время. Взгляните на Листинга 2-6 и Рисунок 2-8.

 

Листинг 2-6. Код для функции Start-ProgressBar


function Start-ProgressBar
{
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $true)]
    $Title,
    [Parameter(Mandatory = $true)]
    [int]$Timer
  )
  For ($i = 1; $i -le $Timer; $i++)
  {
    Start-Sleep -Seconds 1;
    Write-Progress -Activity $Title -Status "$i" -PercentComplete ($i /100 * 100)
  }
} #Function Start-ProgressBar
 	   

Start-ProgressBar -Title "Test timeout" -Timer 30
		
 

Рисунок 2-8


Полоска Start-ProgressBar с таймером в 30 секунд

Вы также можете применить простой таймаут, который является встроенным (смотрите Рисунок 2-9).


timeout 10
		
 

Рисунок 2-9


Встроенный командлет таймаута

Выводы

В этой главе вы изучили командлеты даты и журналов и то как манипулировать форматом дат и применять их для выработки папок и файлов с временной отметкой. Эта технология поможет вам в различных ситуациях, например, при создании файлов журналов или папок журналов на ежедневной основе со вставленными в само название файла отметками даты/ времени.