{"id":18048099,"url":"https://github.com/startautomating/psdevops","last_synced_at":"2026-03-09T04:07:57.223Z","repository":{"id":38288899,"uuid":"222329349","full_name":"StartAutomating/PSDevOps","owner":"StartAutomating","description":"PowerShell Tools for DevOps","archived":false,"fork":false,"pushed_at":"2024-09-15T21:37:14.000Z","size":1245,"stargazers_count":149,"open_issues_count":44,"forks_count":31,"subscribers_count":12,"default_branch":"master","last_synced_at":"2026-02-11T09:31:08.269Z","etag":null,"topics":["azure-devops","devops","github-actions","github-workflow","pipeline","powershell"],"latest_commit_sha":null,"homepage":"https://psdevops.start-automating.com","language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StartAutomating.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-17T23:55:59.000Z","updated_at":"2026-01-29T23:56:04.000Z","dependencies_parsed_at":"2024-02-07T17:00:08.555Z","dependency_job_id":"a4221058-cd59-46a0-a3c3-98d56f902b1c","html_url":"https://github.com/StartAutomating/PSDevOps","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/StartAutomating/PSDevOps","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StartAutomating%2FPSDevOps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StartAutomating%2FPSDevOps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StartAutomating%2FPSDevOps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StartAutomating%2FPSDevOps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StartAutomating","download_url":"https://codeload.github.com/StartAutomating/PSDevOps/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StartAutomating%2FPSDevOps/sbom","scorecard":{"id":133873,"data":{"date":"2025-08-04","repo":{"name":"github.com/StartAutomating/PSDevOps","commit":"df15e7849deb7612aaa55da6f5d45a79c6efb316"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":3.4,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/14 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/OnIssue.yml:1","Warn: no topLevel permission defined: .github/workflows/TestAndPublish.yml:1","Warn: no topLevel permission defined: .github/workflows/TraceIssueClosed.yml:1","Warn: no topLevel permission defined: .github/workflows/TraceIssueComment.yml:1","Warn: no topLevel permission defined: .github/workflows/TraceIssueOpenedOrEdited.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/OnIssue.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/OnIssue.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/OnIssue.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/OnIssue.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:578: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:580: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:583: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:585: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:587: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:120: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:191: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/TestAndPublish.yml:201: update your workflow using https://app.stepsecurity.io/secureworkflow/StartAutomating/PSDevOps/TestAndPublish.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T05:52:43.522Z","repository_id":38288899,"created_at":"2025-08-16T05:52:43.523Z","updated_at":"2025-08-16T05:52:43.523Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30282750,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure-devops","devops","github-actions","github-workflow","pipeline","powershell"],"created_at":"2024-10-30T20:11:35.797Z","updated_at":"2026-03-09T04:07:57.204Z","avatar_url":"https://github.com/StartAutomating.png","language":"PowerShell","readme":"﻿\u003cdiv align='center'\u003e\r\n\u003cimg src='Assets/PSDevOps.svg' /\u003e\r\n\u003c/div\u003e\r\n\r\nPowerShell Tools for DevOps\r\n---------------------------\r\n[![Gallery Downloads](https://img.shields.io/powershellgallery/dt/PSDevOps)](https://www.powershellgallery.com/packages/PSDevOps/)\r\n[![Build Status](https://dev.azure.com/StartAutomating/PSDevOps/_apis/build/status/StartAutomating.PSDevOps?branchName=master)](https://dev.azure.com/StartAutomating/PSDevOps/_build/latest?definitionId=5)\r\n[![Build Status](https://github.com/StartAutomating/Irregular/actions/workflows/IrregularTests.yml/badge.svg)](https://github.com/StartAutomating/PSDevOps/actions/workflows/TestAndPublish.yml)\r\n---------------------------\r\n\r\n__PSDevOps helps you automate DevOps using PowerShell.__\r\n\r\n### What is PSDevOps?\r\n\r\nPSDevOps is a PowerShell module that makes it easier to automate DevOps with PowerShell.\r\n\r\n* [Automate Azure DevOps](#Automate-Azure-DevOps)\r\n* [Creating Complex Pipelines](#Creating-Complex-Pipelines)\r\n* [Dealing with DevOps](#Dealing-with-DevOps)\r\n* [Get the GitHub API](#PSDevOps-GitHub-API)\r\n* [Write GitHub Actions](#Write-GitHub-Actions)\r\n* [Write GitHub Workflows](#Write-GitHub-Workflows)\r\n\r\n#### What do you mean 'Easier to Automate'?\r\n\r\nIf you're familiar with PowerShell, you might know about the Object Pipeline.  \r\nThis allows you to pass objects together, instead of parsing text at each step.\r\nWhile this is great, not many PowerShell commands or REST apis take full advantage of this feature.\r\n\r\nPSDevOps does.\r\n\r\nAlmost every command in PSDevOps is pipeline-aware.  \r\nRelated commands can often be piped together, and command results can often be piped back into a command to return additional information.\r\n\r\nAdditionally, PSDevOps output is often 'decorated' with extended type information.\r\n\r\nThis allows the PowerShell types and formatting engine to extend the return object and customize it's display.\r\n\r\n### Automate Azure DevOps\r\n\r\nThe Azure DevOps REST API can be challenging to work with, and hard to remember.\r\n\r\nPSDevOps provides dozens of commands to automate Azure DevOps.\r\n\r\nCommands are named simply and clearly, using PowerShell's verb-noun convention, for example, Get-ADOProject, Get-ADORepository, Get-ADOBuild\r\n\r\nTo see all commands from PSDevOps, run:\r\n\r\n~~~PowerShell\r\nGet-Command -Module PSDevOps\r\n~~~\r\n\r\nUnlike many modules, these commands make use of the full feature set of PowerShell.\r\nHere are a few things PSDevOps does differently:\r\n\r\n#### Using the Object Pipeline\r\n\r\nThe Object Pipeline is a core feature of PowerShell that allows you to send structured information from step to step.\r\n\r\nAlmost every function in PSDevOps is \"pipeline aware\", and can accept multiple types of objects\r\n\r\n~~~PowerShell\r\nConnect-ADO -Organization $MyOrganization -PersonalAccessToken $MyPat\r\nGet-ADOProject | Get-ADOTeam | Get-ADODashboard\r\n~~~\r\n\r\nMany commands can be piped back into themselves to return additional results, for instance:\r\n\r\n~~~PowerShell\r\nGet-ADOBuild -Project MyProject -First 5 | # Get the first 5 builds \r\n    Get-ADOBuild -ChangeSet # Get the associated changesets.\r\n~~~\r\n\r\n~~~PowerShell\r\nGet-ADOAgentPool | # Gets agent pools from the organization\r\n    Get-ADOAgentPool  # Gets individual agents within a pool, because the prior object returned a PoolID.\r\n~~~\r\n\r\n\r\n#### Invoke-ADORESTApi\r\n\r\nIn orer to ensure that you can always work with Azure DevOps, even if there isn't already a function in PSDevOps, there's Invoke-ADORestAPI.\r\n\r\nInvoke-ADORestAPI can be used like Invoke-RESTMethod, and also has a number of additional features.\r\n\r\nFor instance:\r\n\r\n* -AsJob (Launch long-running queries as a job)\r\n* -Body (autoconverted to JSON)\r\n* -ExpandProperty (Expand out a particular property from output)\r\n* -PSTypeName (apply decoration to output)\r\n* -UrlParameter (Replace parameters within a URL)\r\n* -QueryParameter (Pass parameters within a querystring)\r\n\r\n#### Help\r\n\r\nLike any good PowerShell module, PSDevOps has help.  Run Get-Help on any command to learn more about how to use it.\r\n\r\n~~~PowerShell\r\nGet-Help Get-ADOBuild -Full\r\n~~~\r\n\r\nCommands that wrap the REST api should have a .LINK to the MSDN documentation on the API to help you understand what they are doing.\r\n\r\n#### Custom Formatting\r\n\r\nThe Azure DevOps REST API can return a lot of unhelpful information.\r\nTo make it easier to work with Azure DevOps in Powershell, PSDevOps includes several custom formatters.\r\n\r\nFor a simple example, try running one of the following commands:\r\n\r\n~~~PowerShell\r\nGet-ADOProject\r\n~~~\r\n\r\n~~~PowerShell\r\nGet-ADOTeam -Mine\r\n~~~\r\n\r\n#### Extended Types\r\n\r\nThe Azure DevOps REST api often returns data that is inconsistently named or weakly typed.  \r\n\r\nWhere possible, PSDevOps uses the Extended Type System in PowerShell to augment the values returned from Azure DevOps.\r\n\r\nFor example, when you run Get-ADOAgentPool, it will add two properties to the return value:\r\nPoolID (an alias to ID) and DateCreated (which converts the string date in .CreatedOn to a [DateTime]).\r\n\r\n\r\n#### Supporting -WhatIf and -Confirm\r\n\r\nMost commands in PSDevOps that change system state SupportShouldProcess, and have the automatic parameters -WhatIf and -Confirm.\r\n\r\n-Confirm works the same in PSDevOps as it does in any PowerShell module.  Passing -Confirm will always prompt for confirmation, and Passing -Confirm:$false will never prompt for confirmation.\r\n\r\nPSDevOps does a bit better than most modules when it comes to supporting -WhatIf.  In most modules, -WhatIf will write a message to the host about what might have run.  In PSDevOps, passing -WhatIf should return the values about to be passed to the REST API.\r\n\r\n~~~PowerShell\r\nNew-ADOProject -Name Foo -Description bar -Confirm # Prompts for confirmation\r\n\r\nNew-ADOProject -Name Foo -Description bar -WhatIf  # Returns the data that would be passed to the REST endpoint. \r\n~~~  \r\n\r\n### Creating Complex Pipelines\r\n\r\nWhile Azure DevOps templates are nice, they don't give you syntax highlighting for the scripts of each step.  \r\nAlso, cross-repository templates can be painful.\r\n\r\nPSDevOps allows you to create Azure DevOps pipelines using New-ADOPipeline.  \r\n\r\nFor instance, this create a cross-platform test of the current repository's PowerShell module.\r\n\r\n~~~PowerShell\r\nNew-ADOPipeline -Job TestPowerShellOnLinux, TestPowerShellOnMac, TestPowerShellOnWindows\r\n~~~\r\n\r\nThis creates a multistage pipeline that does PowerShell static analysis, tests the current module (crosssplatform),\r\nand updates the PowerShell gallery using a Secret: \r\n\r\n~~~PowerShell\r\nNew-ADOPipeline -Stage PowerShellStaticAnalysis, TestPowerShellCrossPlatform, UpdatePowerShellGallery\r\n~~~\r\n\r\nThis little one liner works wonderfully to build a CI/CD pipeline in Azure DevOps around almost any PowerShell modules.\r\n\r\nParts are stored in a \\ado\\PartName\\ as either a .ps1 or a .psd1 file.\r\nPS1 files will implicitly become script tasks.\r\nPSD1 files will be treated as task metadata, and can reference other parts.\r\n\r\nAny module that contains an \\ADO directory and is tagged 'PSDevOps' or requires PSDevOps can contain parts.\r\nParts found in these modules will override parts found in PSDevOps.\r\n\r\n#### Advanced Azure DevOps Pipeline Logging\r\n\r\nPSDevOps can also be used to help you write information to the a pipeline's timeline.  This can be considerably easier than memorizing the [Logging Commands Documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands).\r\n\r\nPSDevOps makes this much nicer by abstracting away this ugliness into easy-to-use commands:\r\n\r\n* Add-ADOAttachment\r\n* Set-ADOBuild\r\n* Set-ADOEndpoint\r\n* Set-ADOVariable\r\n* Write-ADOError\r\n* Write-ADOProgress\r\n* Write-ADOWarning\r\n\r\n\r\n### Dealing with DevOps\r\n\r\n\r\nDevOps is a hybrid discipline combining the skillset of Devolopers and Operations.  \r\nWith DevOps, the focus is on automation, and PowerShell is often the language of choice.\r\n\r\nBy convention, most developers write their scripts according to a psuedostandard:\r\n\r\n\u003e ```*-*.ps1``` Scripts containing a function  \r\n\u003e ```*.*.ps1``` 'Special' Scripts, often used by particular modules\r\n\u003e ```*.ps1``` Simple scripts that are run interactively.\r\n\r\n\r\nPSDevOps has a command, Get-PSDevOps, that helps to identify these scripts and their requirements.\r\n\r\n~~~PowerShell\r\nGet-Module PSDevOps | Get-PSDevOps\r\n~~~\r\n\r\n\r\n### PSDevOps GitHub API\r\n\r\nPSDevOps also provides a few functions to work with the GitHub API.\r\n\r\n* Connect/Disconnect-GitHub\r\n* Invoke-GitHubRESTAPI\r\n\r\nInvoke-GitHubRESTAPI works like Invoke-ADORestAPI, as a general-purpose wrapper for GitHub REST API calls.\r\n\r\nIt also has a number of additional features, for example:\r\n\r\n* -AsJob (Launch long-running queries as a job)\r\n* -Body (autoconverted to JSON)\r\n* -ExpandProperty (Expand out a particular property from output)\r\n* -PSTypeName (apply decoration to output)\r\n* -UrlParameter (Replace parameters within a URL)\r\n* -QueryParameter (Pass parameters within a querystring)\r\n\r\nBecause GitHub's REST api is predictable and exposed with OpenAPI, Invoke-GitHubRESTAPI also enables two very interesting scenarios:\r\n\r\n1. Connect-GitHub can automatically create a shortcut for every endpoint in the GitHub API\r\n2. Invoke-GitHubRESTAPI can automatically decorate return values more apporopriately.\r\n\r\nThis means that PSDevOps can integrate with GitHub's REST API with a very small amount of code, and easily customize how GitHub output displays and works in PowerShell.\r\n\r\n### Write GitHub Actions\r\n\r\nYou can automatically generate GitHub actions off of any PowerShell script or command.\r\n\r\nFirst, create a /GitHub/Actions folder in your module directory, then put one or more .ps1 files in it.\r\n\r\nThen, \r\n~~~PowerShell\r\nImport-BuildStep -ModuleName YourModule\r\n~~~\r\n\r\nThen, you can generate your action.yml with some code like this.\r\n\r\n~~~PowerShell\r\nNew-GitHubAction -Name \"Name Of Action\" -Description 'Action Description' -Action MyAction -Icon minimize -ActionOutput ([Ordered]@{\r\n    SomeOutput = [Ordered]@{\r\n        description = \"Some Output\"\r\n        value = '${{steps.MyAction.outputs.SomeOutput}}'\r\n    }    \r\n})\r\n~~~\r\n\r\n### Write GitHub Workflows\r\n\r\nYou can use PSDevOps to write complex Github Workflows using the same techniques as Azure DevOps pipelines:\r\n\r\n~~~PowerShell\r\nNew-GitHubWorkflow -Name RunPester -On Demand, Push, PullRequest -Job TestPowerShellOnLinux\r\n~~~  \r\n\r\nAs with Azure DevOps, parts of the workflow can be defined within the \\GitHub subdirectory of PSDevOps or any module.\r\n\r\n#### Advanced GitHub Workflow Logging\r\n\r\nPSDevOps also includes commands to make logging within a GitHub workflow easier.  They are:\r\n\r\n* Hide-GitHubOutput\r\n* Write-GitHubDebug\r\n* Write-GitHubError\r\n* Write-GitHubOutput\r\n* Write-GitHubWarning","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstartautomating%2Fpsdevops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstartautomating%2Fpsdevops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstartautomating%2Fpsdevops/lists"}