Я пытаюсь понять, почему эти две строки не равны. Есть ли лучший оператор, который я должен использовать?
$lastupdated = invoke-webrequest -uri $source | Исходящая строка -поток | Select-String Last-Modified
$storeddate = получить содержимое C:\windows\file.txt
Как вы определяете, что это относится к string типам?





Я добавил .ToString() при сохранении строки в файл, и теперь мой оператор, похоже, работает.
$lastupdated.ToString() | out-file c:\windows\file.txt
$lastupdated -ne $storeddayed
True
Действительно означает, что значения не идентичны, даже их основные свойства (отображаемые значения) кажутся одинаковыми.
PowerShell — это свободно типизированная программа, которая позволяет «удобно» сравнивать два значения разного типа. Попробуй это:
$lastupdated.GetType()
$storeddayed.GetType()
Я подозреваю, что переменная $storeddayed на самом деле является строкой, поскольку имя подразумевает, что она была сохранена, где она, вероятно, потеряла свою точность фактической структуры даты и времени , поскольку она была либо преобразована автоматически , либо «вручную», как вы делаете в своем собственном ответе методом ToString().
Если сравнивать два разных типа объектов. Объект в правой части экрана (правая сторона) диктует диалог для сравнения (как правило, это имеет значение для любого другого оператора).
Это означает, что вы можете просто преобразовать правую часть (или обе стороны) в строку (используя двойные кавычки):
"$lastupdated" -ne "$storeddayed"
Или просто поменяйте местами операнты в операции, чтобы получить то, что вы ожидали:
$storeddayed -ne $lastupdated
Также обратите внимание, что в случае, если оба операнта ($storeddayed и $lastupdated) имеют структуру datetime, не все подробные свойства отображаются по умолчанию (вспомните информацию о часовом поясе и, например, свойство millisecond).
Другими словами, если вы даете команды за один раз:
$lastupdated = Get-Date()
$storeddayed = Get-Date()
Они могут выглядеть так же, как вы их отображаете (в виде строки), но на самом деле они различаются по времени:
$lastupdated.Millisecond
$storeddayed.Millisecond
В зависимости от того, как вы инициализируете $storeaddate...
$storeddate = get-content C:\windows\file.txt
... Я собираюсь предположить, что в вашем файле есть только одна строка текста с чем-то вроде этого.
Last-Modified Web 17, May 2023 23:27:24 GMT
... что делает его экземпляром [string].
Принимая во внимание, что $lastupdated инициализируется следующим образом:
$lastupdated = invoke-webrequest -uri $source | Out-String -Stream | Select-String Last-Modified
что означает, что это объект Microsoft.PowerShell.Commands.MatchInfo, потому что это то, что возвращает Select-String.
Вы можете проверить это с помощью этого:
$lastupdated.GetType().FullName
# Microsoft.PowerShell.Commands.MatchInfo
и вы можете увидеть более подробную информацию с этим:
$lastupdated | fl *
# IgnoreCase : True
# LineNumber : 1
# Line : Last-Modified Web 17, May 2023 23:27:24 GMT
# Filename : InputStream
# Path : InputStream
# Pattern : Last-Modified
# Context :
# Matches : {0}
Причина, по которой вы $storeddate -ne $lastupdated всегда возвращает $true, заключается в том, что [string] и [matchinfo] никогда не равны.
Если вы хотите получить текстовое (т.е. [string]) представление возвращаемого значения из Select-String, вы можете сделать это:
$lastupdated = invoke-webrequest -uri $source `
| Out-String -Stream `
| Select-String Last-Modified `
| select-object -ExpandProperty "Line"
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - extract the "Line" property value
$lastupated
# Last-Modified Web 17, May 2023 23:27:24 GMT
(обратите внимание на select-object -ExpandProperty "Line", который извлекает значение свойства Line из объекта matchinfo)
И теперь $lastupdated действительно является [string], а не MatchInfo, и вы должны обнаружить, что $storeddate -ne $lastupdated будет правильно возвращать $false, когда они одинаковы.
Last-Modified ЗаголовокСказав все это, я собираюсь сделать небольшой скачок и предположить, что вы действительно на самом деле после заголовка ответа Last-Modified от вашего вызова к invoke-webrequest, который вы можете сделать намного проще, если сделаете это:
$response = invoke-webrequest -uri $source
$lastupdated = $response.Headers["Last-Modified"]
$lastupdated
# Web 17, May 2023 23:27:24 GMT
на который не повлияют различия в хрупком преобразовании ответа, прежде чем вы извлечете Last-Modified с помощью select-string.
И, если вы используете заголовок Last-Modified, чтобы решить, был ли обновлен ресурс, вы также можете использовать метод HEAD, чтобы избежать загрузки всего содержимого ресурса, поскольку это то, чего вы пытаетесь избежать в первом случае. место, если оно уже обновлено:
$response = invoke-webrequest `
-Uri "www.google.com" `
-Method "HEAD" `
-UseBasicParsing
$lastupdated = $response.Headers["Last-Modified"]
$lastupdated
# Web 17, May 2023 23:27:24 GMT
это
DateTimeобъекты, а не строки, поэтому они не работают так, как вы хотите