Powershell — найди следующую пятницу

Надеюсь, это не будет слишком сложно, но я пишу скрипт, который запрашивает информацию о пользователе из домена и экспортирует ее в CSV.

Сценарий запускается нашим административным персоналом, и все, что им нужно ввести в сценарий, — это имя пользователя.

Сложность заключается в том, что мне нужно, чтобы CSV был назван на основе предстоящей пятницы.

Note: I am in Australia so my date format is DD-MM-YYYY

То, как я сейчас смотрю на это, выглядит следующим образом:

# Grab the Script Run Timestamp
$ScriptRuntime = Get-Date -Day 4 -Month 5 -Year 2013

# Grab the next Friday (including today)
$NextFriday = $ScriptRuntime.AddDays(0 + $(0,1,2,3,4,5,6 -eq 5 - [int]$ScriptRuntime.dayofweek))

Write-Host "Script Run:  "$ScriptRuntime
Write-Host "Next Friday: "$NextFriday

Это работает нормально со всеми днями, кроме субботы.

  • Если я запускаю день как День 26, Месяц 5, Год 2013, он возвращает 31/05/2013.
  • Если я запускаю день как День 27, Месяц 5, Год 2013, он возвращает 31/05/2013.
  • Если я запускаю день как День 28, Месяц 5, Год 2013, он возвращает 31/05/2013.
  • Если я запускаю день как День 29, Месяц 5, Год 2013, он возвращает 31/05/2013.
  • Если я запускаю день как День 30, Месяц 5, Год 2013, он возвращает 31/05/2013
  • Если я запускаю день как День 31, Месяц 5, Год 2013, он возвращает 31/05/2013
  • Если я запускаю день как День 1, Месяц 6, Год 2013, он возвращает 31.05.2013 (это должно быть 06.07.2013)
  • Если я запускаю день как День 2, Месяц 6, Год 2013, он возвращает 06.07.2013.

Что я делаю не так?


person davidwedrat    schedule 28.05.2013    source источник


Ответы (9)


Я не уверен, что слежу за вами, но вот что я получу в следующую пятницу:

$date = Get-Date

for($i=1; $i -le 7; $i++)
{        
    if($date.AddDays($i).DayOfWeek -eq 'Friday')
    {
        $date.AddDays($i)
        break
    }
}
person Shay Levy    schedule 28.05.2013
comment
Любой, кто ищет, возможно, менее понятную, но более компактную конструкцию конвейера, может попробовать что-то вроде 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Friday'} - person Code Jockey; 27.10.2016
comment
Я хотел бы отметить, что для того, чтобы $date имело значение следующей пятницы, оно должно быть фактически назначено, поэтому $date = $date.AddDays($i) вместо просто $date.AddDays($i) - person iMassakre; 10.08.2017

Это находит следующую пятницу:

$date = Get-Date
while ($Date.DayOfWeek -ne "Friday") {$date = $date.AddDays(1)}
person StephenSo    schedule 07.01.2016

Вот однострочник, который тоже поможет:

$Date = @(@(0..7) | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -ieq "Friday"})[0]

И если вам нужно конкретное время:

$Date = @(@(0..7) | % {$(Get-Date "12:00").AddDays($_)} | ? {($_ -gt $(Get-Date)) -and ($_.DayOfWeek -ieq "Friday")})[0]
person shogan    schedule 29.05.2014
comment
Какова цель самого внешнего объявления массива (@(...))? - person jpmc26; 20.09.2016
comment
вам не понадобится [0] в конце, если вы просто поместите либо (0..6) или (1..7) впереди, в зависимости от желаемого поведения (я полагаю, что 0..6 ответит OP) - person Code Jockey; 02.11.2016

Вы можете получить дату пятницы на этой неделе, независимо от того, в какую дату вы запускаете код, используя следующее:

$today = (Get-Date).Date    
$nextfriday = $today.AddDays([int][dayofweek]::Friday - $today.DayOfWeek)    

Если вы хотите всегда получать следующую пятницу (то есть пятницу следующей недели, если вы бегаете в субботу), вам просто нужен дополнительный модификатор в конце:

if ($today -ge $nextfriday) {$nextfriday = $nextfriday.AddDays(7)}
person bf.    schedule 14.05.2018

Немного опоздал на вечеринку, но вот мой вариант (без циклов, без условий):

    [datetime] $MyDate =  get-date
    [DayOfWeek] $NextDayOfWeek = 'Friday'

    $MyDate.AddDays( (7 - [int] $MyDate.DayOfWeek + [int] $NextDayOfWeek )%7 )

Если вы хотите проверить его для большего количества дат:

    [datetime] $MyDate =  get-date
    [DayOfWeek] $NextDayOfWeek = 'Friday'

    1..30 | ForEach-Object {
                            [PSCustomObject]@{ 
                                DayOfWeek = $MyDate.DayOfWeek ;
                                Date = $MyDate; 
                                $("Next$NextDayOfWeek") = $MyDate.AddDays((7 - [int] $MyDate.DayOfWeek + [int] $NextDayOfWeek )%7)   
                            }; 
                            $MyDate = $MyDate.AddDays(1)  
                        } 
person Bert Van Landeghem    schedule 16.10.2019

Попробуйте это, чтобы найти следующую пятницу:

$ScriptRuntime = Get-Date -Day 4 -Month 5 -Year 2013
$i= switch ( [int][dayofweek]::Friday - [int] $ScriptRuntime.dayofweek )
    { 
       -1 { 6 }
       default { $_ }
    } 
$ScriptRuntime.adddays($i)
person CB.    schedule 28.05.2013

Я бы сделал это так:

$Date = Get-Date
$targetDay = [int][dayofweek]::Friday
# I use this logic to figure out the next Friday
# else we would get Friday of this week
$intToday = if([int]$Date.DayOfWeek -le [int][dayofweek]::Friday ){
                [int]$Date.DayOfWeek 
            } else { 
                [int]$Date.DayOfWeek - 7
            }
$nextFriday = $date.AddDays($targetDay - $intToday)

Я столкнулся с той же проблемой, но подумал, что использование цикла - это слишком много. Я нашел статью о PowerShell Find Date предыдущего дня любой недели, но значения, жестко закодированные для дней, и в зависимости от среды Windows воскресенье могут не иметь индекс 0 (ноль). Итак, я использовал логику как вдохновение и понял то, что выше.

Надеюсь, это поможет следующему парню.

person Aaron C    schedule 04.01.2016

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

Function Find-NextDate {
[CmdletBinding()]
param (
    # Parameter help description
    [Parameter(Mandatory=$true,
    Position=1)]
    [validatenotnullorempty()]
    [ValidateSet("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")]
    [string]$Day,
    [Parameter(Mandatory=$false,
    Position=2)]
    [validatenotnullorempty()]
    [string]$Time
)
process {
    if ($Time) {
        $Date = (Get-Date $Time)
        for($i=1; $i -le 7; $i++) {        
            if ($Date.AddDays($i).DayOfWeek -eq "$Day") {
                $Date.AddDays($i)
                break
            }
        }
    }
    else {
        $Date = (Get-Date)
        for($i=1; $i -le 7; $i++) {        
            if ($Date.AddDays($i).DayOfWeek -eq "$Day") {
                $Date.AddDays($i)
                break
            }
        }
    }
}

}

person Немања Јовић    schedule 11.04.2019

Вы можете установить модуль ProductivityTools.PSGetDayInGivenWeek из галереи PowerShell.

Install-Module -Name ProductivityTools.PSGetDayInGivenWeek

Он предоставляет метод Get-RequestedDayOfWeek, который позволяет определить, какой день недели вы ищете, и если вы ищете его до или после указанного дня. Итак, чтобы найти следующий понедельник

Get-RequestedDayOfWeek '2018.03.03' -Monday -After

Модуль в галерее PowerShell можно найти здесь, а код для него здесь.

введите здесь описание изображения

person Pawel Wujczyk    schedule 18.09.2018
comment
Загрузка стороннего пакета для тривиальных вещей, на мой взгляд, действительно бесполезна (это также отупляет разработчиков, поскольку они понятия не имеют, что происходит в фоновом режиме, если они только устанавливают пакеты, написанные другими, вместо того, чтобы найти способ заставить вещи работать, особенно для действительно тривиальных вещей). - person bluuf; 15.01.2019
comment
Я пытаюсь не копировать и не вставлять код, который был написан один раз. Разработчики всегда могут проанализировать код на Github и, возможно, что-то узнать. Также наличие его в модуле и ссылки на него из других скриптов помогает исправить функциональность везде, если в исходном скрипте будет допущена какая-то ошибка. - person Pawel Wujczyk; 16.01.2019