{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Богдан Стефанюк: дописи з тегом powershell",
    "_rss_description": "Всім привіт! Я — Богдан, фулстек розробник з Києва. Пишу в основному про програмування та штуки які вивчаю. Час від часу публікую підбірки фоток, зроблених на плівку, розказую про подорожі та цікаві речі, що оточують мене.",
    "_rss_language": "uk",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/stefaniuk.website\/tags\/powershell\/",
    "feed_url": "https:\/\/stefaniuk.website\/tags\/powershell\/json\/",
    "icon": "https:\/\/stefaniuk.website\/pictures\/userpic\/userpic@2x.jpg?1565716580",
    "authors": [
        {
            "name": "Bohdan Stefaniuk",
            "url": "https:\/\/stefaniuk.website\/",
            "avatar": "https:\/\/stefaniuk.website\/pictures\/userpic\/userpic@2x.jpg?1565716580"
        }
    ],
    "items": [
        {
            "id": "76",
            "url": "https:\/\/stefaniuk.website\/all\/work-with-file-system-in-powershell\/",
            "title": "Работа с файлами в Powershell",
            "content_html": "<p><b>Получение списка файлов<\/b><\/p>\n<ul>\n<li><i>Get-ChildItem $path<\/i> — отобразит список файлов по указанному пути.<\/li>\n<li><i>Get-ChildItem -Force $path<\/i> — отобразит список файлов (включая скрытые) по указанному пути.<\/li>\n<li><i>Get-ChildItem -Force $path -Recurse<\/i> — отобразит список всех файлов, а также вложенных.<\/li>\n<\/ul>\n<p><b>Копирование файлов и папок<\/b><\/p>\n<ul>\n<li><i>New-Item -Path $path -ItemType «directory | file»<\/i> — создает объект в файловой системе.<\/li>\n<\/ul>\n<p><b>Удаление всех файлов и папок, содержащихся в папке<\/b><\/p>\n<ul>\n<li><i>Remove-Item $path<\/i> — удалит все файлы по указанному пути, но будет предлагать подтверждения.<\/li>\n<li><i>Remove-Item $path -Recurse<\/i> — удалит все файлы без подтверждения.<\/li>\n<\/ul>\n<p><b>Работа с содержимым файла<\/b><\/p>\n<ul>\n<li><i>Get-Content -Path $path<\/i> — вычитать содержимое файла.<\/li>\n<li><i>Add-Content -Path $path «Additional content»<\/i> — дописывает в конец файла текст.<\/li>\n<li><i>Set-Content -Path $path -Value «New content»<\/i> — позволяет перезаписать содержимое файла<\/li>\n<li><i>Get-Date | Set-Content $path<\/i> — также можно использовать в качестве пайпалайна<\/li>\n<li><i>Out-File -FilePath $path<\/i> — отправляет вывод в файл.<\/li>\n<li><i>Out-File -FilePath $path -Append<\/i> — дописывает данные в конец файла<\/li>\n<\/ul>\n",
            "date_published": "2019-06-19T08:35:12-04:00",
            "date_modified": "2019-06-19T08:33:44-04:00",
            "tags": [
                "powershell",
                "програмування"
            ],
            "_date_published_rfc2822": "Wed, 19 Jun 2019 08:35:12 -0400",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "76",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "62",
            "url": "https:\/\/stefaniuk.website\/all\/automate-github-releases-by-powershell-and-teamcity\/",
            "title": "Автоматизация релизов Github с помощью Powershell и Teamcity",
            "content_html": "<p>Совсем недавно о одном open-source проекте, в котором я участвую, потребовалось автоматизировать создание релизов на Github. В моем распоряжении есть TeamCity. Решил написать небольшой план, который состоит из следующих шагов:<\/p>\n<ol start=\"1\">\n<li>Выкачать проект.<\/li>\n<li>Скомпилировать.<\/li>\n<li>Опубликовать Release версию в папку.<\/li>\n<li>Собрать артефакт Teamcity.<\/li>\n<li>Упаковать билд в архив.<\/li>\n<li>Создать страницу релиза на Github с описанием.<\/li>\n<li>Выгрузить на страницу архив с билдом.<\/li>\n<\/ol>\n<p>Для решения 5-6 пунктов был написан простой powershell скрипт, который можно посмотреть по <a href=\"https:\/\/github.com\/teamkiller7112\/PowerShellScriptsArchive\/blob\/master\/Greate-GithubRelease.ps1\">этой ссылке.<\/a><\/p>\n<p>P.S. В дальнейшем, в репозиторий буду добавлять друге полезные скрипты.<br \/>\nСсылка на репозиторий: <a href=\"https:\/\/github.com\/teamkiller7112\/PowerShellScriptsArchive\">https:\/\/github.com\/teamkiller7112\/PowerShellScriptsArchive<\/a><\/p>\n",
            "date_published": "2019-05-14T07:03:53-04:00",
            "date_modified": "2019-05-13T14:04:49-04:00",
            "tags": [
                "powershell",
                "програмування"
            ],
            "_date_published_rfc2822": "Tue, 14 May 2019 07:03:53 -0400",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "62",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "60",
            "url": "https:\/\/stefaniuk.website\/all\/best-practices-for-using-powershell-with-teamcity\/",
            "title": "Лучшие практики использования PowerShell c TeamCity",
            "content_html": "<p>Данная статья является переводом. <a href=\"https:\/\/cezarypiatek.github.io\/post\/best-practices-for-using-powershell-with-teamcity\/?utm_campaign=dotNET%20Weekly&utm_medium=email&utm_source=week-15_year-2019\">Оригинальная статья<\/a>.<\/p>\n<h2>Правильная обработка ошибок<\/h2>\n<p>Наиболее распространенная проблема заключается в том, что TeamCity игнорирует ошибки Powershell, по крайней мере, в конфигурации по умолчанию. Если шаг со сценарием PowerShell завершится неудачно, TeamCity по-прежнему считает билд успешным. Это может привести к серьезным ошибкам, которые могут быть незаметны длительное время. Это происходит потому что значение настройки <i>Format stderr output as<\/i> установлено в <i>warning<\/i>. Для того чтобы TeamCity видел ошибки, необходимо переключить настройку в <i>error<\/i>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/stefaniuk.website\/pictures\/error_handling_for_ps.jpg\" width=\"917\" height=\"576\" alt=\"\" \/>\n<\/div>\n<p>Но это еще не все. Может возникнуть ситуация что шаг PowerShell упал но весь пайплайн признан успешным. Для этого нужно перейти в раздел <i>Failure Conditions<\/i> и установить флаг <i>error message is logged by build runner<\/i>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/stefaniuk.website\/pictures\/teamcity_failure_condition.jpg\" width=\"848\" height=\"312\" alt=\"\" \/>\n<\/div>\n<p>Теперь все ошибки буду корректно обрабатываться и влиять на статус билда.<\/p>\n<p>Также надо понимать модель ошибок в PowerShell. Они могут поделятся на 2 группы:<\/p>\n<ol start=\"1\">\n<li>Завершающие (зачастую синтаксические ошибки).<\/li>\n<li>Не завершающие.<\/li>\n<\/ol>\n<p>Если возникло не завершающее исключение, то выполнение скрипта продолжится. Этот эффект может быть крайне нежелательным для сценариев, выполняющих взаимосвязанные операции, зависящие друг от друга. Конечно, мы можем изменить это поведение и превратить все «не завершающиеся» ошибки в «завершающиеся», установив переменную $ErrorActionPreference в начале наших скриптов:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">#Error Action Preference:\r\n#\r\n# SilentlyContinue – error messages are suppressed and execution continues.\r\n# Stop – forces execution to stop, behaving like a terminating error.\r\n# Continue - the default option. Errors will display and execution will continue.\r\n# Inquire – prompt the user for input to see if we should proceed.\r\n# Ignore – (new in v3) – the error is ignored and not logged to the error stream. Has very restricted usage scenarios.\r\n\r\n$ErrorActionPreference = &quot;Stop&quot;<\/code><\/pre><h2>Защита от случайных ошибок<\/h2>\n<p>Для начала необходимо превратить все наши функции в настоящие командлеты. Для этого нужно определять входящие параметры с помощью блока <i>param()<\/i> и пометить его атрибутом <i>[CmdletBinding()]<\/i>:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">function Verb-Noun {\r\n    [CmdletBinding()]\r\n    param (\r\n     #parameters go here   \r\n    )    \r\n}<\/code><\/pre><p>Этот атрибут защищает вызов метода с не определенными параметрами. Каждый раз как кто-то использует не определенный\/удаленный параметр или делает ошибку в его названии, PowerShell выбросит ошибку. Если метод не помечен атрибутов, имена параметров не проверяются, что затрудняет обнаружение проблемы.<\/p>\n<p>Также можно обнаружить потенциальные ошибки, вызванные нарушением лучших практик и правил кодирования, включив строгий режим. Чтобы сделать это, добавьте следующий код в начале вашего скрипта:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">Set-StrictMode -Version Latest<\/code><\/pre><p>Детальнее можно почитать <a href=\"https:\/\/docs.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/set-strictmode?view=powershell-6\">тут<\/a>.<\/p>\n<p>Вообще советую использовать VS Core и плагином PowerShell. Он превращает вашу в IDE в аналог PowerShell ISE. Также этот плагин поставляется с PSScriptAnalyzer, что позволяет обнаруживать разные ошибки.<\/p>\n<h2>Использование скриптов<\/h2>\n<p>Teamcity дает возможность запускать скрипты не только из файла, но и из встроенного редактора. Но лучшей практикой считается использование файлов. Это позволит держать скрипты в системе контроля версий, вместе с вашим проектом.<\/p>\n<h2>Всегда помните о чистом коде.<\/h2>\n<p>Ваши скрипты как и код вашего проекта должен лежать в системе контроля версий, покрыт тестами и пройти ревью. <a href=\"https:\/\/github.com\/PoshCode\/PowerShellPracticeAndStyle\">Здесь<\/a> вы можете найти лучшие практики и стили кодирования для PowerShell. Для тестирования кода можете использовать — <a href=\"https:\/\/github.com\/pester\/Pester\">Pester<\/a>.<\/p>\n<h2>Итог<\/h2>\n<p>Связка PowerShell и Teamcity позволяет создать действительно мощный CI\/CD. Но без понимания базовых принципов и механизмов вы не достигните максимального профита. Настройки по умолчанию часто могут приводить к непредвиденным ошибкам.<\/p>\n<h2>Ссылки<\/h2>\n<ol start=\"1\">\n<li><a href=\"https:\/\/github.com\/PoshCode\/PowerShellPracticeAndStyle\">Практики и стили кодирования для PowerShell скриптов.<\/a><\/li>\n<li>((<a href=\"https:\/\/github.com\/pester\/Pester\">https:\/\/github.com\/pester\/Pester<\/a> Pester — тест и мок фреймворк для PowerShell.)<\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/set-strictmode?view=powershell-6\">PowerShell strict mode<\/a>.<\/li>\n<\/ol>\n",
            "date_published": "2019-05-12T13:57:44-04:00",
            "date_modified": "2020-12-26T16:42:06-04:00",
            "tags": [
                "powershell",
                "перевод"
            ],
            "image": "https:\/\/stefaniuk.website\/pictures\/error_handling_for_ps.jpg",
            "_date_published_rfc2822": "Sun, 12 May 2019 13:57:44 -0400",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "60",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/stefaniuk.website\/pictures\/error_handling_for_ps.jpg",
                    "https:\/\/stefaniuk.website\/pictures\/teamcity_failure_condition.jpg"
                ]
            }
        },
        {
            "id": "45",
            "url": "https:\/\/stefaniuk.website\/all\/powershell-credentials\/",
            "title": "PowerShell: создание Credentials.",
            "content_html": "<p>Для того чтобы работать с авторизацией пользователя в powershell существую следующие понятия:<br \/>\n<b>String<\/b> — простая строка, в ней можно сохранять пароль, но не желательно, так как она хранится в памяти в открытом виде.<br \/>\n<b>System.Security.SecureString<\/b> — выглядит как обычная строка, но она зашифрована. Она использует «обратимое» шифрование, так что мы в любой момент можем декодировать пароль.<br \/>\n<b>System.Management.Automation.PSCredential<\/b> — класс, который содержит в себе логин и зашифрованный пароль. Данный тип есть почти у каждой команды, которая поддерживает авторизацию.<\/p>\n<h2>Создание SecureString<\/h2>\n<pre class=\"e2-text-code\"><code class=\"\"># Чтение из консоли\r\n$SecurePassword = Read-Host -Prompt &quot;Enter password&quot; -AsSecureString\r\n\r\n# Чтение из переменной\r\n$PlainPassword = &quot;P@ssw0rd&quot;\r\n$SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force<\/code><\/pre><h2>Создание PSCredentials<\/h2>\n<pre class=\"e2-text-code\"><code class=\"\">$UserName = &quot;Domain\\User&quot;\r\n$Credentials = New-Object System.Management.Automation.PSCredential `\r\n     -ArgumentList $UserName, $SecurePassword<\/code><\/pre><h2>Получение пароля из PSCredentials<\/h2>\n<pre class=\"e2-text-code\"><code class=\"\">$PlainPassword = $Credentials.GetNetworkCredential().Password<\/code><\/pre><h2>Получение пароля из SecureString<\/h2>\n<p>Можно создать PSCredentials и получить из них пароль, но есть и другой способ:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">$BSTR = `\r\n    [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)\r\n$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)<\/code><\/pre><h2>Лучшие подходы<\/h2>\n<ul>\n<li>Старайтесь не спрашивать у пользователя пароль, а по максимуму используйте Windows authentication.<\/li>\n<li>Никогда не держите пароли в чистом виде, только в SecureString или PSCredentials<\/li>\n<li>Если вам нужно запросить учетные данные у пользователя, используйте командлет Get-Credential. Он использует стандартную функцию Windows для последовательного и безопасного получения пароля без сохранения его в памяти в виде открытого текста.<\/li>\n<\/ul>\n",
            "date_published": "2019-04-04T16:54:17-04:00",
            "date_modified": "2019-04-04T16:52:39-04:00",
            "tags": [
                "powershell"
            ],
            "_date_published_rfc2822": "Thu, 04 Apr 2019 16:54:17 -0400",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "45",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        }
    ],
    "_e2_version": 4116,
    "_e2_ua_string": "Aegea 11.2 (v4116)"
}