Найдите переменную для строки, затем запустите условный оператор в PowerShell

Я новичок в PowerShell. Недавно мне было поручено создать всплывающее окно с сообщением об ошибке, которое помогло бы локальному пользователю определить, работает ли слияние БД по запросу MS SQL или нет. Я написал скрипт, который будет делать следующее:

  • Run the batch file that conducted the merge
  • Read the results of a text log file into a variable
  • Check the variable for any instances of the word "ERROR" and pop a success or fail dialog box depending on whether or not it found the word error in the log file.

    Быстро и просто, подумал я, но, похоже, я борюсь с условным оператором. Вот сценарий:

    cmd /c c:\users\PERSON\desktop\merge.bat
    
    $c = get-content c:\replmerg.log
    
    if ($c -contains ("ERROR"))
    {
        $a = new-object -comobject wscript.shell
        $b = $a.popup(“ERROR - Database Merge“,0,”Please Contact Support”,1)
    }
    
    else
    {
        $a = new-object -comobject wscript.shell
        $b = $a.popup(“SUCCESS - Database Merge“,0,”Good Job!”,1)
    }
    

    Прямо сейчас происходит то, что сценарий запускается и просто переходит к сообщению об успехе. Я могу подтвердить, что простой запуск команды «get-content» в powershell сам по себе создаст переменную, которую я затем могу вызвать и показать содержимое файла журнала. Мой сценарий, однако, не выглядит так, как будто он на самом деле проверяет переменную $c на наличие слова, а затем выводит сообщение об ошибке, как предполагалось. Что мне здесь не хватает?


  • person Tyson Navarre    schedule 04.05.2011    source источник


    Ответы (5)


    Ответ Кристиана правильный. Вы также можете использовать оператор -match. Например:

    if ((Get-Content c:\replmerg.log) -match "ERROR")
    {
        'do error stuff'
    }
    else
    {
        'do success stuff'
    }
    

    Вы можете использовать -cmatch, если вам нужно сравнение с учетом регистра.

    person Greg Wojan    schedule 04.05.2011
    comment
    По какой-то причине Грег, ваше утверждение if сработало, когда Кристиан дал тот же результат. В любом случае, огромное спасибо! - person Tyson Navarre; 04.05.2011
    comment
    Пожалуйста. :) На самом деле, причина, по которой Кристиан if терпит неудачу, заключается в том, что $c на самом деле имеет тип matchinfo и не имеет длины. имущество. При таких проблемах всегда полезно знать, с каким типом вы имеете дело. Играйте с различными версиями, которые вы пробовали каждый раз, проверяя $c.gettype(). - person Greg Wojan; 04.05.2011

    На самом деле вам вообще не нужно использовать Get-Content. Select-String может принимать параметр -path. Я создал два очень простых текстовых файла, в одном из которых есть слово ERROR, а в другом нет.

    PS C:\> cat .\noerror.txt
    not in here
    PS C:\> cat .\haserror.txt
    ERROR in here
    this has ERROR in here
    PS C:\> if ( Select-String  -Path .\noerror.txt -Pattern ERROR) {"Has Error"}
    PS C:\> if ( Select-String  -Path .\haserror.txt -Pattern ERROR) {"Has Error"}
    Has Error
    PS C:\>
    

    Единственное, что может сбить вас с толку, это то, что -шаблон на самом деле принимает регулярное выражение, поэтому будьте осторожны с тем, что вы используете для своего шаблона. Это найдет ОШИБКУ в любом месте файла журнала, даже если есть несколько экземпляров, например, в моем файле «haserror.txt».

    person Andy Schneider    schedule 04.05.2011

    Оператор -contains используется для поиска точного совпадения в списке (или массиве). Как показывают другие ответы, вы должны использовать -match, -like или -eq для сравнения строк.

    person Mike Shepard    schedule 04.05.2011

    Вы можете использовать переключатель -quiet команды select-string, если вы просто хотите проверить наличие строки в файле.

    select-string -path c:\replmerg.log -pattern "ERROR" -casesensetive -quiet
    

    Возвращает $true, если строка найдена в файле, и $false, если нет.

    person mjolinor    schedule 06.05.2011

    содержать оператор test только идентичное значение (не часть значения).

    Вы можете попробовать это

    $c = get-content c:\replmerg.log | select-string "ERROR" -casesensitive
    
    if ($c.length -gt 0)
    
    person CB.    schedule 04.05.2011
    comment
    Попытался вставить его, и он все равно просто пропускает первый оператор IF и выдает сообщение об успешном завершении. Спасибо за помощь! - person Tyson Navarre; 04.05.2011
    comment
    странно... симуляция здесь отличная работа! Может быть, ОШИБКА написана в нижнем регистре? - person CB.; 04.05.2011
    comment
    на самом деле нет свойства length для работы сравнения, потому что $c имеет тип matchinfo, если есть совпадения, в противном случае $c равно $null. Использование if ($c) { } else { должно работать нормально, потому что вы являетесь неявным if ($c -eq $null). - person Greg Wojan; 05.05.2011
    comment
    @Greg: ты прав! В моем тесте, прежде чем опубликовать ответ, я использовал файл с большим количеством совпадений! Я был уверен (без тестирования, большая ошибка), что всегда возвращаемый тип был объектом массива. Благодарю вас! - person CB.; 05.05.2011