├── .config └── dotnet-tools.json ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── general-question.md ├── PULL_REQUEST_TEMPLATE.md ├── SECURITY.md └── workflows │ ├── Docs.yml │ ├── NotifyOnStarred.yml │ ├── Publish.yml │ └── Test.yml ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── LICENSE ├── PSScriptAnalyzerSettings.psd1 ├── build.ps1 ├── docs ├── README.md ├── assets │ └── images │ │ ├── example-notification.jpg │ │ ├── joshooaj.png │ │ ├── pushover-icon-256.png │ │ ├── pushover-icon-512.png │ │ ├── pushover-logo.svg │ │ └── star.png └── en-US │ ├── Get-PushoverConfig.md │ ├── Get-PushoverSound.md │ ├── Get-PushoverStatus.md │ ├── Reset-PushoverConfig.md │ ├── Send-Pushover.md │ ├── Set-PushoverConfig.md │ ├── Test-PushoverUser.md │ └── Wait-Pushover.md ├── joshooaj.PSPushover ├── Classes │ ├── MessagePriority.ps1 │ ├── PSPushoverInformationLevel.ps1 │ ├── PSPushoverNotificationStatus.ps1 │ └── PSPushoverUserValidation.ps1 ├── Private │ ├── ConvertTo-PlainText.ps1 │ ├── Import-PushoverConfig.ps1 │ ├── Save-PushoverConfig.ps1 │ └── Send-MessageWithAttachment.ps1 ├── Public │ ├── Get-PushoverConfig.ps1 │ ├── Get-PushoverSound.ps1 │ ├── Get-PushoverStatus.ps1 │ ├── Reset-PushoverConfig.ps1 │ ├── Send-Pushover.ps1 │ ├── Set-PushoverConfig.ps1 │ ├── Test-PushoverUser.ps1 │ └── Wait-Pushover.ps1 ├── joshooaj.PSPushover.psd1 └── joshooaj.PSPushover.psm1 ├── mkdocs.yml ├── psakeFile.ps1 ├── requirements.psd1 ├── requirements.txt ├── tests ├── Help.tests.ps1 ├── Manifest.tests.ps1 ├── Meta.tests.ps1 ├── MetaFixers.psm1 └── ScriptAnalyzerSettings.psd1 └── version.json /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "nbgv": { 6 | "version": "3.6.133", 7 | "commands": [ 8 | "nbgv" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------------------------------------- 2 | # Copyright (c) Microsoft Corporation. All rights reserved. 3 | # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 4 | #------------------------------------------------------------------------------------------------------------- 5 | 6 | FROM squidfunk/mkdocs-material:latest 7 | 8 | # This Dockerfile adds a non-root user with sudo access. Use the "remoteUser" 9 | # property in devcontainer.json to use it. On Linux, the container user's GID/UIDs 10 | # will be updated to match your local UID/GID (when using the dockerFile property). 11 | # See https://aka.ms/vscode-remote/containers/non-root-user for details. 12 | ARG USERNAME=vscode 13 | ARG USER_UID=1000 14 | ARG USER_GID=$USER_UID 15 | 16 | # install git iproute2, process tools 17 | RUN apk add --no-cache \ 18 | ca-certificates \ 19 | less \ 20 | ncurses-terminfo-base \ 21 | krb5-libs \ 22 | libgcc \ 23 | libintl \ 24 | libssl1.1 \ 25 | libstdc++ \ 26 | tzdata \ 27 | userspace-rcu \ 28 | zlib \ 29 | icu-libs \ 30 | curl \ 31 | git \ 32 | openssh-client \ 33 | less \ 34 | procps \ 35 | gpg \ 36 | bash \ 37 | shadow \ 38 | sudo && \ 39 | apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache lttng-ust && \ 40 | # Download the powershell '.tar.gz' archive \ 41 | curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/powershell-7.4.1-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz && \ 42 | # Create the target folder where powershell will be placed 43 | mkdir -p /opt/microsoft/powershell/7 && \ 44 | # Expand powershell to the target folder 45 | tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && \ 46 | # Set execute permissions 47 | chmod +x /opt/microsoft/powershell/7/pwsh && \ 48 | # Create the symbolic link that points to pwsh 49 | ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \ 50 | # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user. 51 | addgroup -g $USER_GID $USERNAME && \ 52 | adduser -s /usr/bin/pwsh -u $USER_UID -G $USERNAME -D $USERNAME && \ 53 | # [Optional] Add sudo support for the non-root user 54 | echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME && \ 55 | chmod 0440 /etc/sudoers.d/$USERNAME && \ 56 | # Clean up 57 | apk cache clean && \ 58 | rm /tmp/powershell.tar.gz 59 | USER $USERNAME 60 | ENTRYPOINT [ "/usr/bin/pwsh" ] 61 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PowerShell", 3 | "dockerFile": "Dockerfile", 4 | "customizations": { 5 | "vscode": { 6 | "settings": { 7 | "terminal.integrated.profiles.linux": { 8 | "bash": { 9 | "path": "usr/bin/bash", 10 | "icon": "terminal-bash" 11 | }, 12 | "zsh": { 13 | "path": "usr/bin/zsh" 14 | }, 15 | "pwsh": { 16 | "path": "/usr/bin/pwsh", 17 | "icon": "terminal-powershell" 18 | } 19 | }, 20 | "terminal.integrated.defaultProfile.linux": "pwsh" 21 | }, 22 | "extensions": ["ms-vscode.powershell", "davidanson.vscode-markdownlint", "redhat.vscode-yaml"] 23 | } 24 | }, 25 | "postCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", 26 | "postStartCommand": "pwsh -c 'sudo chown -R \"$(id -u):$(id -g)\" $PWD; ./build.ps1 -Task Init -Bootstrap'", 27 | "forwardPorts": [8000], 28 | "remoteUser": "vscode" 29 | } 30 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * -crlf 2 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, sexual identity and 10 | orientation, or sexual proclivities between consenting adults. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 26 | * Trolling, insulting/derogatory comments, and personal or political attacks 27 | * Public or private harassment 28 | * Publishing others' private information, such as a physical or electronic 29 | address, without explicit permission 30 | * Other conduct which could reasonably be considered inappropriate in a 31 | professional setting 32 | 33 | ## Our Responsibilities 34 | 35 | Project maintainers are responsible for clarifying the standards of acceptable 36 | behavior and are expected to take appropriate and fair corrective action in 37 | response to any instances of unacceptable behavior. 38 | 39 | Project maintainers have the right and responsibility to remove, edit, or 40 | reject comments, commits, code, wiki edits, issues, and other contributions 41 | that are not aligned to this Code of Conduct, or to ban temporarily or 42 | permanently any contributor for other behaviors that they deem inappropriate, 43 | threatening, offensive, or harmful. 44 | 45 | ## Scope 46 | 47 | This Code of Conduct applies both within project spaces and in public spaces 48 | when an individual is representing the project or its community. Examples of 49 | representing a project or community include using an official project e-mail 50 | address, posting via an official social media account, or acting as an appointed 51 | representative at an online or offline event. Representation of a project may be 52 | further defined and clarified by project maintainers. 53 | 54 | ## Enforcement 55 | 56 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 57 | reported by contacting the project team at [joshooaj@gmail.com](mailto:joshooaj@gmail.com). All 58 | complaints will be reviewed and investigated and will result in a response that 59 | is deemed necessary and appropriate to the circumstances. The project team is 60 | obligated to maintain confidentiality with regard to the reporter of an incident. 61 | Further details of specific enforcement policies may be posted separately. 62 | 63 | Project maintainers who do not follow or enforce the Code of Conduct in good 64 | faith may face temporary or permanent repercussions as determined by other 65 | members of the project's leadership. 66 | 67 | ## Attribution 68 | 69 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4.1, 70 | available at [http://contributor-covenant.org/version/1/4/1][version] 71 | 72 | [homepage]: http://contributor-covenant.org 73 | [version]: http://contributor-covenant.org/version/1/4/ 74 | 75 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Contributions to PSPushover are highly encouraged and desired. 4 | Below are some guidelines that will help make the process as smooth as possible. 5 | 6 | ## Getting Started 7 | 8 | - Make sure you have a [GitHub account](https://github.com/signup/free) 9 | - Submit a new issue, assuming one does not already exist. 10 | - Clearly describe the issue including steps to reproduce when it is a bug. 11 | - Make sure you fill in the earliest version that you know has the issue. 12 | - Fork the repository on GitHub 13 | 14 | ## Suggesting Enhancements 15 | 16 | I want to know what you think is missing from PSPushover and how it can be made better. 17 | 18 | - When submitting an issue for an enhancement, please be as clear as possible about why you think the enhancement is needed and what the benefit of it would be. 19 | 20 | ## Making Changes 21 | 22 | - From your fork of the repository, create a topic branch where work on your change will take place. 23 | - To quickly create a topic branch based on master; `git checkout -b my_contribution master`. 24 | Please avoid working directly on the `master` branch. 25 | - Make commits of logical units. 26 | - Check for unnecessary whitespace with `git diff --check` before committing. 27 | - Please follow the prevailing code conventions in the repository. 28 | Differences in style make the code harder to understand for everyone. 29 | - Make sure your commit messages are in the proper format. 30 | 31 | ``` 32 | Add more cowbell to Get-Something.ps1 33 | 34 | The functionality of Get-Something would be greatly improved if there was a little 35 | more 'pizzazz' added to it. I propose a cowbell. Adding more cowbell has been 36 | shown in studies to both increase one's mojo, and cement one's status 37 | as a rock legend. 38 | ``` 39 | 40 | - Make sure you have added all the necessary Pester tests for your changes. 41 | - Run _all_ Pester tests in the module to assure nothing else was accidentally broken. 42 | 43 | ## Documentation 44 | 45 | I am infallible and as such my documenation needs no corectoin. 46 | In the highly unlikely event that that is _not_ the case, commits to update or add documentation are highly apprecaited. 47 | 48 | ## Submitting Changes 49 | 50 | - Push your changes to a topic branch in your fork of the repository. 51 | - Submit a pull request to the main repository. 52 | - Once the pull request has been reviewed and accepted, it will be merged with the master branch. 53 | - Celebrate 54 | 55 | ## Additional Resources 56 | 57 | - [General GitHub documentation](https://help.github.com/) 58 | - [GitHub forking documentation](https://guides.github.com/activities/forking/) 59 | - [GitHub pull request documentation](https://help.github.com/send-pull-requests/) 60 | - [GitHub Flow guide](https://guides.github.com/introduction/flow/) 61 | - [GitHub's guide to contributing to open source projects](https://guides.github.com/activities/contributing-to-open-source/) 62 | 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Expected Behavior 4 | 5 | 6 | 7 | ## Current Behavior 8 | 9 | 10 | 11 | ## Possible Solution 12 | 13 | 14 | 15 | ## Steps to Reproduce (for bugs) 16 | 17 | 18 | 1. 19 | 2. 20 | 3. 21 | 4. 22 | 23 | ## Context 24 | 25 | 26 | 27 | ## Your Environment 28 | 29 | * Module version used: 30 | * Operating System and PowerShell version: 31 | 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: joshooaj 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment (please complete the following information):** 27 | - PSPushover version [e.g. 0.1.15] 28 | - OS: [e.g. Linux, Windows, macOS] 29 | - PowerShell version [e.g. 5.1, 7.4.1] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: joshooaj 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General question 3 | about: Ask a general question 4 | title: '' 5 | labels: question 6 | assignees: joshooaj 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Related Issue 7 | 8 | 9 | 10 | 11 | 12 | ## Motivation and Context 13 | 14 | 15 | ## How Has This Been Tested? 16 | 17 | 18 | 19 | 20 | ## Screenshots (if appropriate): 21 | 22 | ## Types of changes 23 | 24 | - [ ] Bug fix (non-breaking change which fixes an issue) 25 | - [ ] New feature (non-breaking change which adds functionality) 26 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 27 | 28 | ## Checklist: 29 | 30 | 31 | - [ ] My code follows the code style of this project. 32 | - [ ] My change requires a change to the documentation. 33 | - [ ] I have updated the documentation accordingly. 34 | - [ ] I have read the **CONTRIBUTING** document. 35 | - [ ] I have added tests to cover my changes. 36 | - [ ] All new and existing tests passed. 37 | 38 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Security vulnerabilities may be reported on any version, and your reports 6 | are greatly appreciated. Patches may be released for the current major 7 | version, and the previous major version. 8 | 9 | | Version | Supported | 10 | | ------- | ------------------ | 11 | | 0.1.x | :white_check_mark: | 12 | 13 | ## Reporting a Vulnerability 14 | 15 | You are welcome to report a security vulnerability by opening a GitHub 16 | issue, or if it feels more appropriate, you may send an email to 17 | joshooaj@gmail.com 18 | with "SECURITY DISCLOSURE" in the subject. 19 | 20 | I will make an effort to address the issue within 30 days. If you are able 21 | to provide sample code to demonstrate the issue, or submit a pull request 22 | with your proposed fix, that would be a great help. 23 | -------------------------------------------------------------------------------- /.github/workflows/Docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - docs/** 10 | - mkdocs.yml 11 | - .github/workflows/Docs.yml 12 | 13 | jobs: 14 | DeployDocs: 15 | # Grant the minimum permissions necessary for this job to publish to GitHub Pages 16 | permissions: 17 | contents: write 18 | pages: write 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | with: 23 | fetch-depth: 0 24 | 25 | - uses: actions/cache@v4.2.3 26 | with: 27 | key: ${{ runner.os }} 28 | path: .cache 29 | 30 | - name: Load PSDepend Requirements 31 | id: psdepend 32 | shell: pwsh 33 | run: | 34 | $reqs = Import-PowerShellDataFile ./requirements.psd1 35 | $moduleNames = $reqs.Keys | Where-Object { $_ -ne 'PSDependOptions' -and $null -eq $reqs[$_].DependencyType } 36 | $dependencyList = ($moduleNames | Sort-Object | ForEach-Object { '{0}:{1}' -f $_, $reqs[$_].Version }) -join ', ' 37 | "psdependencies=$dependencyList" >> $env:GITHUB_OUTPUT 38 | 39 | # - name: Install and cache PowerShell modules 40 | # uses: potatoqualitee/psmodulecache@v6.2 41 | # with: 42 | # modules-to-cache: ${{ steps.psdepend.outputs.psdependencies }} 43 | 44 | - id: image-cache 45 | uses: actions/cache@v4.2.3 46 | with: 47 | key: ${{ runner.os }}-docker-cache 48 | path: .docker 49 | 50 | - name: Cache docker image 51 | if: steps.image-cache.outputs.cache-hit != 'true' 52 | shell: pwsh 53 | run: | 54 | $null = New-Item .docker/ -ItemType Directory -Force 55 | docker pull squidfunk/mkdocs-material:9 56 | docker save -o ./.docker/mkdocs-material.tar squidfunk/mkdocs-material:9 57 | 58 | - if: steps.image-cache.outputs.cache-hit == 'true' 59 | run: docker load -i ./.docker/mkdocs-material.tar 60 | 61 | - name: MkDocs GH-Deploy 62 | if: github.ref == 'refs/heads/main' 63 | shell: pwsh 64 | run: .\build.ps1 -Bootstrap -Task PublishDocs 65 | -------------------------------------------------------------------------------- /.github/workflows/NotifyOnStarred.yml: -------------------------------------------------------------------------------- 1 | name: NotifyOnStarred 2 | on: 3 | watch: 4 | types: [started] 5 | 6 | jobs: 7 | notify: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - name: SendNotification 12 | env: 13 | PUSHOVER_APP_TOKEN: ${{ secrets.PUSHOVER_APP_TOKEN }} 14 | PUSHOVER_GROUP_TOKEN: ${{ secrets.PUSHOVER_GROUP_TOKEN }} 15 | shell: pwsh 16 | run: | 17 | Import-Module ./joshooaj.PSPushover/joshooaj.PSPushover.psd1 18 | $msg = @{ 19 | Message = 'Someone ⭐''d the repo 🎉' 20 | Sound = 'magic' 21 | Attachment = [io.file]::ReadAllBytes((Resolve-Path ./docs/assets/images/star.png)) 22 | FileName = 'star.png' 23 | Url = 'https://github.com/joshooaj/PSPushover' 24 | UrlTitle = 'github.com/joshooaj/PSPushover' 25 | Token = $env:PUSHOVER_APP_TOKEN | ConvertTo-SecureString -AsPlainText -Force 26 | User = $env:PUSHOVER_GROUP_TOKEN | ConvertTo-SecureString -AsPlainText -Force 27 | } 28 | Send-Pushover @msg 29 | -------------------------------------------------------------------------------- /.github/workflows/Publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | workflow_run: 5 | workflows: ["Test"] 6 | types: 7 | - completed 8 | 9 | jobs: 10 | publish: 11 | if: | 12 | github.event.workflow_run.conclusion == 'success' && 13 | startsWith(github.event.workflow_run.head_branch, 'v') 14 | name: Publish 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | 21 | - uses: actions/cache@v4.2.3 22 | with: 23 | key: ${{ runner.os }} 24 | path: .cache 25 | 26 | - name: Load PSDepend Requirements 27 | id: psdepend 28 | shell: pwsh 29 | run: | 30 | $reqs = Import-PowerShellDataFile ./requirements.psd1 31 | $moduleNames = $reqs.Keys | Where-Object { $_ -ne 'PSDependOptions' -and $null -eq $reqs[$_].DependencyType } 32 | $dependencyList = ($moduleNames | Sort-Object | ForEach-Object { '{0}:{1}' -f $_, $reqs[$_].Version }) -join ', ' 33 | "psdependencies=$dependencyList" >> $env:GITHUB_OUTPUT 34 | 35 | # - name: Install and cache PowerShell modules 36 | # uses: potatoqualitee/psmodulecache@v6.2 37 | # with: 38 | # modules-to-cache: ${{ steps.psdepend.outputs.psdependencies }} 39 | 40 | - name: Publish 41 | env: 42 | PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} 43 | shell: pwsh 44 | run: ./build.ps1 -Task Publish -Bootstrap 45 | -------------------------------------------------------------------------------- /.github/workflows/Test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - v* 8 | branches: 9 | - main 10 | paths-ignore: 11 | - .github/workflows/Docs.yml 12 | - .github/workflows/NotifyOnStarred.yml 13 | - .github/workflows/Publish.yml 14 | pull_request: 15 | branches: 16 | - main 17 | paths-ignore: 18 | - .github/workflows/Docs.yml 19 | - .github/workflows/Publish.yml 20 | 21 | jobs: 22 | test: 23 | name: Test 24 | runs-on: ${{ matrix.os }} 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | os: [ubuntu-latest, windows-latest, macOS-latest] 29 | steps: 30 | - uses: actions/checkout@v4 31 | with: 32 | fetch-depth: 0 33 | 34 | - uses: actions/cache@v4.2.3 35 | with: 36 | key: ${{ runner.os }} 37 | path: .cache 38 | 39 | - name: Load PSDepend Requirements 40 | id: psdepend 41 | shell: pwsh 42 | run: | 43 | $reqs = Import-PowerShellDataFile ./requirements.psd1 44 | $moduleNames = $reqs.Keys | Where-Object { $_ -ne 'PSDependOptions' -and $null -eq $reqs[$_].DependencyType } 45 | $dependencyList = ($moduleNames | Sort-Object | ForEach-Object { '{0}:{1}' -f $_, $reqs[$_].Version }) -join ', ' 46 | "psdependencies=$dependencyList" >> $env:GITHUB_OUTPUT 47 | 48 | # - name: Install and cache PowerShell modules 49 | # uses: potatoqualitee/psmodulecache@v6.2 50 | # with: 51 | # modules-to-cache: ${{ steps.psdepend.outputs.psdependencies }} 52 | 53 | - name: Test 54 | shell: pwsh 55 | run: ./build.ps1 -Task Test -Bootstrap 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check in the Output dir 2 | Output/ 3 | 4 | scratch/ 5 | 6 | testResults.xml 7 | 8 | .dotnet/ 9 | 10 | .cache/ 11 | 12 | .docker/ 13 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "ms-vscode.PowerShell", 6 | "DavidAnson.vscode-markdownlint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "PowerShell: Launch Current File", 9 | "type": "PowerShell", 10 | "request": "launch", 11 | "script": "${file}", 12 | "args": [], 13 | "createTemporaryIntegratedConsole": true 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.autoSave": "onFocusChange", 3 | "files.autoSaveWorkspaceFilesOnly": true, 4 | "files.insertFinalNewline": true, 5 | "files.trimTrailingWhitespace": true, 6 | "editor.insertSpaces": true, 7 | "editor.tabSize": 4, 8 | "powershell.codeFormatting.preset": "OTBS", 9 | "yaml.schemas": { 10 | "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" 11 | }, 12 | "yaml.customTags": [ 13 | "!ENV scalar", 14 | "!ENV sequence", 15 | "!relative scalar", 16 | "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg", 17 | "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji", 18 | "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | 6 | // Start PowerShell (pwsh on *nix) 7 | "windows": { 8 | "options": { 9 | "shell": { 10 | "executable": "powershell.exe", 11 | "args": [ "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command" ] 12 | } 13 | } 14 | }, 15 | "linux": { 16 | "options": { 17 | "shell": { 18 | "executable": "/usr/bin/pwsh", 19 | "args": [ "-NoProfile", "-Command" ] 20 | } 21 | } 22 | }, 23 | "osx": { 24 | "options": { 25 | "shell": { 26 | "executable": "/usr/local/bin/pwsh", 27 | "args": [ "-NoProfile", "-Command" ] 28 | } 29 | } 30 | }, 31 | 32 | "tasks": [ 33 | { 34 | "label": "Clean", 35 | "type": "shell", 36 | "command": "${cwd}/build.ps1 -Task Clean -Verbose" 37 | }, 38 | { 39 | "label": "Test", 40 | "type": "shell", 41 | "command": "${cwd}/build.ps1 -Task Test -Verbose", 42 | "group": { 43 | "kind": "test", 44 | "isDefault": true 45 | }, 46 | "problemMatcher": "$pester" 47 | }, 48 | { 49 | "label": "Analyze", 50 | "type": "shell", 51 | "command": "${cwd}/build.ps1 -Task Analyze -Verbose" 52 | }, 53 | { 54 | "label": "Pester", 55 | "type": "shell", 56 | "command": "${cwd}/build.ps1 -Task Pester -Verbose", 57 | "problemMatcher": "$pester" 58 | }, 59 | { 60 | "label": "Build", 61 | "type": "shell", 62 | "command": "${cwd}/build.ps1 -Task Build -Verbose", 63 | "group": { 64 | "kind": "build", 65 | "isDefault": true 66 | } 67 | }, 68 | { 69 | "label": "Publish", 70 | "type": "shell", 71 | "command": "${cwd}/build.ps1 -Task Publish -Verbose" 72 | } 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Josh Hendricks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /PSScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | Severity = @('Error', 'Warning') 3 | ExcludeRules = @('PSReviewUnusedParameter') 4 | } 5 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding(DefaultParameterSetName = 'Task')] 2 | param( 3 | # Build task(s) to execute 4 | [parameter(ParameterSetName = 'task', position = 0)] 5 | [ArgumentCompleter( { 6 | param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams) 7 | $psakeFile = './psakeFile.ps1' 8 | switch ($Parameter) { 9 | 'Task' { 10 | if ([string]::IsNullOrEmpty($WordToComplete)) { 11 | Get-PSakeScriptTasks -buildFile $psakeFile | Select-Object -ExpandProperty Name 12 | } 13 | else { 14 | Get-PSakeScriptTasks -buildFile $psakeFile | 15 | Where-Object { $_.Name -match $WordToComplete } | 16 | Select-Object -ExpandProperty Name 17 | } 18 | } 19 | Default { 20 | } 21 | } 22 | })] 23 | [string[]]$Task = 'default', 24 | 25 | # Bootstrap dependencies 26 | [switch]$Bootstrap, 27 | 28 | # List available build tasks 29 | [parameter(ParameterSetName = 'Help')] 30 | [switch]$Help, 31 | 32 | # Optional properties to pass to psake 33 | [hashtable]$Properties, 34 | 35 | # Optional parameters to pass to psake 36 | [hashtable]$Parameters 37 | ) 38 | 39 | $ErrorActionPreference = 'Stop' 40 | 41 | # Bootstrap dependencies 42 | if ($Bootstrap.IsPresent) { 43 | Get-PackageProvider -Name Nuget -ForceBootstrap | Out-Null 44 | Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 45 | if ((Test-Path -Path ./requirements.psd1)) { 46 | if (-not (Get-Module -Name PSDepend -ListAvailable)) { 47 | Install-Module -Name PSDepend -Repository PSGallery -Scope CurrentUser -Force 48 | } 49 | Import-Module -Name PSDepend -Verbose:$false 50 | Invoke-PSDepend -Path './requirements.psd1' -Install -Import -Force -WarningAction SilentlyContinue 51 | } else { 52 | Write-Warning 'No [requirements.psd1] found. Skipping build dependency installation.' 53 | } 54 | } 55 | 56 | # Execute psake task(s) 57 | $psakeFile = './psakeFile.ps1' 58 | if ($PSCmdlet.ParameterSetName -eq 'Help') { 59 | Get-PSakeScriptTasks -buildFile $psakeFile | 60 | Format-Table -Property Name, Description, Alias, DependsOn 61 | } else { 62 | Set-BuildEnvironment -Force 63 | Invoke-psake -buildFile $psakeFile -taskList $Task -nologo -properties $Properties -parameters $Parameters 64 | exit ([int](-not $psake.build_success)) 65 | } 66 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # PSPushover 2 | 3 | ![GitHub Actions Test Workflow Status](https://img.shields.io/github/actions/workflow/status/joshooaj/PSPushover/Test.yml?label=build%2Ftest) 4 | ![GitHub Actions Docs Workflow Status](https://img.shields.io/github/actions/workflow/status/joshooaj/PSPushover/Docs.yml?label=docs) 5 | ![GitHub Actions Publish Workflow Status](https://img.shields.io/github/actions/workflow/status/joshooaj/PSPushover/Publish.yml?label=publish) 6 | ![PowerShell Gallery Version](https://img.shields.io/powershellgallery/v/joshooaj.PSPushover) 7 | ![PowerShell Gallery Downloads](https://img.shields.io/powershellgallery/dt/joshooaj.PSPushover) 8 | ![GitHub License](https://img.shields.io/github/license/joshooaj/PSPushover) 9 | [![Built with Material for MkDocs](https://img.shields.io/badge/Material_for_MkDocs-526CFE?style=for-the-badge&logo=MaterialForMkDocs&logoColor=white)](https://squidfunk.github.io/mkdocs-material/) 10 | 11 | The PSPushover PowerShell module makes it a breeze to send push notifications to any device using the 12 | [Pushover](https://pushover.net) service from PowerShell on Windows, Linux, and MacOS. You can send push notifications to Android, iOS, and 13 | desktop devices. 14 | 15 | Each notification is associated with an "application", and can be sent to an individual user, or 16 | to a group of users. Get notified... 17 | 18 | - when backups fail 19 | - when cron jobs run 20 | - when servers restart 21 | - when your GitHub Actions / Azure DevOps / Jenkins / GitLab pipelines fail 22 | - [when someone star's your GitHub repo](https://github.com/joshooaj/PSPushover/blob/main/.github/workflows/NotifyOnStarred.yml) 23 | - __whenever and for whatever you want!__ 24 | 25 | ## :material-star-shooting: Try it out 26 | 27 | ![Screenshot of Pushover notification on iOS](assets/images/example-notification.jpg) 28 | 29 | When this GitHub repository receives a new star, it triggers a GitHub Action [workflow](https://github.com/joshooaj/PSPushover/blob/main/.github/workflows/NotifyOnStarred.yml) which uses PSPushover to send a notification to anyone who subscribes using the link below. 30 | 31 | [Subscribe to Star Notifications](https://pushover.net/subscribe/PSPushover-2hw5raj6uqr5dsw) 32 | 33 | Pushover will generate a random user token for you and add it to a distribution group. You can unsubscribe from your Pushover dashboard at any time, and your real user token is never exposed. So go ahead and try it out! If you already had the repo starred before subscribing, you can unstar and star it again as many times as you like. 34 | 35 | ## :fontawesome-solid-person-walking-arrow-right: Getting started 36 | 37 | All Pushover notifications are sent from an __application__ to a __user__ or __group__. To send 38 | your first push notification, you need an __application token__ and a __user key__. To receive 39 | notifications, you need the Pushover app installed on a mobile device, or at least have the website 40 | open with notifications enabled in a [compatible browser](https://pushover.net/clients/desktop). 41 | 42 | ### Create an application 43 | 44 | Notifications need to come from _something_, and with Pushover, that something is an "application". 45 | The application can be named anything you like. Naming things is hard though, so if you can't 46 | decide on a name, use "PSPushover". 47 | 48 | 1. Register and/or login at [pushover.net](https://pushover.net/login). 49 | 2. Take note of your __user key__. It looks like `ygzttgcfpab5wyrtstnxlrqllpr0et`. 50 | 3. Under __Your Applications__, click __Create an Application/API Token__, fill out the required 51 | fields, and take note of the api key. 52 | 53 | ### Install PSPushover 54 | 55 | ```powershell 56 | Install-Module joshooaj.PSPushover -Scope CurrentUser -Repository PSGallery 57 | ``` 58 | 59 | ### Set default tokens 60 | 61 | You can choose to enter your app and user tokens each time you call `Send-Pushover`, but you 62 | can also save them securely using `Set-PushoverConfig` and then they'll become the default values 63 | when no alternate tokens are provided. 64 | 65 | ```powershell 66 | $appToken = Read-Host -Prompt 'Application token' -AsSecureString 67 | $usrToken = Read-Host -Prompt 'User token' -AsSecureString 68 | Set-PushoverConfig -Token $appToken -User $usrToken 69 | ``` 70 | 71 | ### Send a message 72 | 73 | It's time to send your first push notification! 74 | 75 | ```powershell 76 | Send-Pushover -Message 'Hello from PSPushover!' 77 | ``` 78 | -------------------------------------------------------------------------------- /docs/assets/images/example-notification.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshooaj/PSPushover/e0f4b2df075c9db95fba4f0c3b0f250bb0fc4647/docs/assets/images/example-notification.jpg -------------------------------------------------------------------------------- /docs/assets/images/joshooaj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshooaj/PSPushover/e0f4b2df075c9db95fba4f0c3b0f250bb0fc4647/docs/assets/images/joshooaj.png -------------------------------------------------------------------------------- /docs/assets/images/pushover-icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshooaj/PSPushover/e0f4b2df075c9db95fba4f0c3b0f250bb0fc4647/docs/assets/images/pushover-icon-256.png -------------------------------------------------------------------------------- /docs/assets/images/pushover-icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshooaj/PSPushover/e0f4b2df075c9db95fba4f0c3b0f250bb0fc4647/docs/assets/images/pushover-icon-512.png -------------------------------------------------------------------------------- /docs/assets/images/pushover-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/assets/images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshooaj/PSPushover/e0f4b2df075c9db95fba4f0c3b0f250bb0fc4647/docs/assets/images/star.png -------------------------------------------------------------------------------- /docs/en-US/Get-PushoverConfig.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Get-PushoverConfig/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-PushoverConfig 9 | 10 | ## SYNOPSIS 11 | 12 | Get the Pushover configuration from the PSPushover module 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Get-PushoverConfig [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Properties like the API URI and default application and user tokens can be read and written 23 | using Get-PushoverConfig and Set-PushoverConfig. 24 | 25 | The location of the configuration file depends on your operating system. On Windows the path is 26 | usually `C:\Users\\AppData\Roaming\joshooaj.PSPushover\config.xml` and on Linux the path may 27 | be `/home//.config/joshooaj.PSPushover/config.xml`. PSPushover determines the application 28 | data path using the command `[Environment]::GetFolderPath([System.Environment+SpecialFolder]::ApplicationData)` 29 | 30 | ## EXAMPLES 31 | 32 | ### Example 1 33 | 34 | ```powershell 35 | Get-PushoverConfig | Format-List 36 | 37 | <# Sample output 38 | ApiUri : https://api.pushover.net/1 39 | AppToken : System.Security.SecureString 40 | UserToken : System.Security.SecureString 41 | ConfigPath : /home/vscode/.config/PSPushover/config.xml 42 | #> 43 | ``` 44 | 45 | Returns the PSPushover configuration for the current user which includes the default base URI for the Pushover API, the 46 | default app and user tokens, and the location where the configuration is stored. 47 | 48 | ## PARAMETERS 49 | 50 | ### -ProgressAction 51 | 52 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 53 | 54 | ```yaml 55 | Type: ActionPreference 56 | Parameter Sets: (All) 57 | Aliases: proga 58 | 59 | Required: False 60 | Position: Named 61 | Default value: None 62 | Accept pipeline input: False 63 | Accept wildcard characters: False 64 | ``` 65 | 66 | ### CommonParameters 67 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 68 | 69 | ## INPUTS 70 | 71 | ### None 72 | 73 | ## OUTPUTS 74 | 75 | ### PSCustomObject 76 | 77 | ## NOTES 78 | 79 | ## RELATED LINKS 80 | -------------------------------------------------------------------------------- /docs/en-US/Get-PushoverSound.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Get-PushoverSound/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-PushoverSound 9 | 10 | ## SYNOPSIS 11 | 12 | Gets the sounds available to use for notifications associated with an application. 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Get-PushoverSound [[-Token] ] [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | The `Get-PushoverSound` cmdlet gets the sounds available to use for notifications associated with 23 | an application. There is a collection of sounds available to choose from, and you may add your own 24 | sounds through your [Pushover.net](https://pushover.net) dashboard. 25 | 26 | ## EXAMPLES 27 | 28 | ### Example 1 29 | 30 | ```powershell 31 | Get-PushoverSound 32 | ``` 33 | 34 | Gets a hashtable containing the sounds available for the default application in your environment. 35 | 36 | ### Example 2 37 | 38 | ```powershell 39 | $appToken = Read-Host -Prompt 'Application token' -AsSecureString 40 | Get-PushoverSound -Token $appToken 41 | ``` 42 | 43 | Gets a hashtable containing the sounds available for the application represented by the token 44 | stored in the $appToken variable. 45 | 46 | ## PARAMETERS 47 | 48 | ### -Token 49 | 50 | Specifies the Pushover application API token/key. The default value will be used if it has been 51 | previously set with Set-PushoverConfig. 52 | 53 | ```yaml 54 | Type: SecureString 55 | Parameter Sets: (All) 56 | Aliases: 57 | 58 | Required: False 59 | Position: 0 60 | Default value: None 61 | Accept pipeline input: False 62 | Accept wildcard characters: False 63 | ``` 64 | 65 | ### -ProgressAction 66 | 67 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 68 | 69 | ```yaml 70 | Type: ActionPreference 71 | Parameter Sets: (All) 72 | Aliases: proga 73 | 74 | Required: False 75 | Position: Named 76 | Default value: None 77 | Accept pipeline input: False 78 | Accept wildcard characters: False 79 | ``` 80 | 81 | ### CommonParameters 82 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 83 | 84 | ## INPUTS 85 | 86 | ## OUTPUTS 87 | 88 | ### System.Collections.Hashtable 89 | 90 | ## NOTES 91 | 92 | ## RELATED LINKS 93 | -------------------------------------------------------------------------------- /docs/en-US/Get-PushoverStatus.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Get-PushoverStatus/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-PushoverStatus 9 | 10 | ## SYNOPSIS 11 | 12 | Gets the status of a Pushover notification using the receipt from Send-Pushover. 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Get-PushoverStatus [[-Token] ] [-Receipt] [-ProgressAction ] 18 | [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | 23 | When sending a Pushover notification with MessagePriority of 'Emergency', a receipt is returned. 24 | This receipt is a random string associated with the notification and can be used to check if and 25 | when the notification was delivered and acknowledged, or if it has expired and is no longer 26 | causing notifications to be sent to the user(s). 27 | 28 | When the notification is acknowledged, the user and device performing the acknowledgement will be 29 | included in the returned `[PSPushoverNotificationStatus]` response. 30 | 31 | ## EXAMPLES 32 | 33 | ### EXAMPLE 1 34 | 35 | ```powershell 36 | $receipt = Send-Pushover -Message 'Are we there yet?' -MessagePriority Emergency -Sound tugboat 37 | Get-PushoverStatus -Receipt $receipt 38 | 39 | <# Sample output 40 | 41 | # Before acknowledgement 42 | Receipt : ro3r26sualp9jb71azpp3eizrtfiir 43 | Acknowledged : False 44 | AcknowledgedAt : 01/01/1970 00:00:00 45 | AcknowledgedBy : 46 | AcknowledgedByDevice : 47 | LastDeliveredAt : 03/17/2024 21:47:44 48 | Expired : False 49 | ExpiresAt : 03/17/2024 21:57:44 50 | CalledBack : False 51 | CalledBackAt : 01/01/1970 00:00:00 52 | 53 | # After acknowledgement 54 | Receipt : ro3r26sualp9jb71azpp3eizrtfiir 55 | Acknowledged : True 56 | AcknowledgedAt : 03/17/2024 21:48:50 57 | AcknowledgedBy : 58 | AcknowledgedByDevice : android 59 | LastDeliveredAt : 03/17/2024 21:48:44 60 | Expired : False 61 | ExpiresAt : 03/17/2024 21:57:44 62 | CalledBack : False 63 | CalledBackAt : 01/01/1970 00:00:00 64 | #> 65 | ``` 66 | 67 | Sends an emergency Pushover message and then uses the receipt to check the status of that notification. 68 | 69 | ## PARAMETERS 70 | 71 | ### -Receipt 72 | 73 | Specifies the receipt returned by Send-Pushover when sending notifications with a 74 | "MessagePriority" value of "Emergency". The receipt is a random string value in the same format 75 | as an application or user token. 76 | 77 | ```yaml 78 | Type: String 79 | Parameter Sets: (All) 80 | Aliases: 81 | 82 | Required: True 83 | Position: 1 84 | Default value: None 85 | Accept pipeline input: True (ByValue) 86 | Accept wildcard characters: False 87 | ``` 88 | 89 | ### -Token 90 | 91 | Specifies the Pushover application API token/key. The default value will be used if it has been 92 | previously set with Set-PushoverConfig. 93 | 94 | ```yaml 95 | Type: SecureString 96 | Parameter Sets: (All) 97 | Aliases: 98 | 99 | Required: False 100 | Position: 0 101 | Default value: None 102 | Accept pipeline input: False 103 | Accept wildcard characters: False 104 | ``` 105 | 106 | ### -ProgressAction 107 | 108 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 109 | 110 | ```yaml 111 | Type: ActionPreference 112 | Parameter Sets: (All) 113 | Aliases: proga 114 | 115 | Required: False 116 | Position: Named 117 | Default value: None 118 | Accept pipeline input: False 119 | Accept wildcard characters: False 120 | ``` 121 | 122 | ### CommonParameters 123 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 124 | 125 | ## INPUTS 126 | 127 | ## OUTPUTS 128 | 129 | ### PSPushoverNotificationStatus 130 | 131 | ## NOTES 132 | 133 | ## RELATED LINKS 134 | -------------------------------------------------------------------------------- /docs/en-US/Reset-PushoverConfig.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Reset-PushoverConfig/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Reset-PushoverConfig 9 | 10 | ## SYNOPSIS 11 | 12 | Reset the PSPushover module configuration to default values for the current user. 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Reset-PushoverConfig [-ProgressAction ] [-WhatIf] [-Confirm] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Use this cmdlet to reset your current user's PSPushover configuration to default values. This will 23 | reset the Pushover API base URI to the default value, and remove your user and application tokens 24 | if they were previously stored using `Set-PushoverConfig`. 25 | 26 | ## EXAMPLES 27 | 28 | ### Example 1 29 | 30 | ```powershell 31 | Reset-PushoverConfig 32 | ``` 33 | 34 | Deletes the stored application and user tokens if present, and resets the base URI for the Pushover 35 | API to the default value. 36 | 37 | ## PARAMETERS 38 | 39 | ### -Confirm 40 | Prompts you for confirmation before running the cmdlet. 41 | 42 | ```yaml 43 | Type: SwitchParameter 44 | Parameter Sets: (All) 45 | Aliases: cf 46 | 47 | Required: False 48 | Position: Named 49 | Default value: None 50 | Accept pipeline input: False 51 | Accept wildcard characters: False 52 | ``` 53 | 54 | ### -WhatIf 55 | Shows what would happen if the cmdlet runs. 56 | The cmdlet is not run. 57 | 58 | ```yaml 59 | Type: SwitchParameter 60 | Parameter Sets: (All) 61 | Aliases: wi 62 | 63 | Required: False 64 | Position: Named 65 | Default value: None 66 | Accept pipeline input: False 67 | Accept wildcard characters: False 68 | ``` 69 | 70 | ### -ProgressAction 71 | 72 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 73 | 74 | ```yaml 75 | Type: ActionPreference 76 | Parameter Sets: (All) 77 | Aliases: proga 78 | 79 | Required: False 80 | Position: Named 81 | Default value: None 82 | Accept pipeline input: False 83 | Accept wildcard characters: False 84 | ``` 85 | 86 | ### CommonParameters 87 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 88 | 89 | ## INPUTS 90 | 91 | ## OUTPUTS 92 | 93 | ## NOTES 94 | 95 | ## RELATED LINKS 96 | -------------------------------------------------------------------------------- /docs/en-US/Send-Pushover.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Send-Pushover/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Send-Pushover 9 | 10 | ## SYNOPSIS 11 | 12 | Sends a message to one or more users using the Pushover API. 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Send-Pushover [-Message] [-Title ] [-Attachment ] [-FileName ] [-Url ] 18 | [-UrlTitle ] [-MessagePriority ] [-RetryInterval ] 19 | [-ExpireAfter ] [-Timestamp ] [-Sound ] [-Tags ] [-Token ] 20 | [-User ] [-Device ] [-ProgressAction ] [] 21 | ``` 22 | 23 | ## DESCRIPTION 24 | 25 | The `Send-Pushover` cmdlet sends a message to one or more users using the Pushover API. 26 | Notifications require a message, and may be customized with a number of optional parameters 27 | including a title, image, url, sound, timestamp, and priority. 28 | 29 | Notifications with a MessagePriority of "Emergency" can be customized with a retry interval, and 30 | expiration. Emergency notifications can be monitored in order to track when and who has 31 | acknowledged them. 32 | 33 | ## EXAMPLES 34 | 35 | ### EXAMPLE 1 36 | 37 | ```powershell 38 | Send-PushoverMessage -Token $token -User $user -Title 'What time is it?' -Message 'It''s time for lunch' 39 | ``` 40 | 41 | Sends a notification to the user or group specified in the $user string variable, from the application designed by the application API token value in $token 42 | 43 | ### EXAMPLE 2 44 | 45 | ```powershell 46 | Send-PushoverMessage -Token $token -User $user -Title 'What time is it?' -Message 'It''s time for lunch' -MessagePriority Emergency -RetryInterval (New-TimeSpan -Seconds 60) -ExpireAfter (New-TimeSpan -Hours 1) 47 | ``` 48 | 49 | Sends the same notification as Example 1, except with emergency priority which results in the notification being repeated every 60 seconds, until an hour has passed or the message has been acknowledged. 50 | 51 | ## PARAMETERS 52 | 53 | ### -Attachment 54 | 55 | Optionally specifies an image in bytes to be attached to the message. 56 | 57 | ```yaml 58 | Type: Byte[] 59 | Parameter Sets: (All) 60 | Aliases: 61 | 62 | Required: False 63 | Position: Named 64 | Default value: None 65 | Accept pipeline input: False 66 | Accept wildcard characters: False 67 | ``` 68 | 69 | ### -Device 70 | 71 | Optionally specifies one or more devices to which notifications should be sent. 72 | Useful for sending notifications to a targetted device instead of all of the user's devices. 73 | 74 | ```yaml 75 | Type: String[] 76 | Parameter Sets: (All) 77 | Aliases: 78 | 79 | Required: False 80 | Position: Named 81 | Default value: None 82 | Accept pipeline input: False 83 | Accept wildcard characters: False 84 | ``` 85 | 86 | ### -ExpireAfter 87 | 88 | Specifies the amount of time unacknowledged notifications will be retried before Pushover stops sending notifications. 89 | Valid only with MessagePriority of 'Emergency'. 90 | 91 | ```yaml 92 | Type: TimeSpan 93 | Parameter Sets: (All) 94 | Aliases: 95 | 96 | Required: False 97 | Position: Named 98 | Default value: (New-TimeSpan -Minutes 10) 99 | Accept pipeline input: False 100 | Accept wildcard characters: False 101 | ``` 102 | 103 | ### -FileName 104 | 105 | Optionally specifies the file name to associate with the attachment. 106 | 107 | ```yaml 108 | Type: String 109 | Parameter Sets: (All) 110 | Aliases: 111 | 112 | Required: False 113 | Position: Named 114 | Default value: Attachment.jpg 115 | Accept pipeline input: False 116 | Accept wildcard characters: False 117 | ``` 118 | 119 | ### -Message 120 | 121 | Specifies the message to be sent with the Pushover notification. 122 | 123 | ```yaml 124 | Type: String 125 | Parameter Sets: (All) 126 | Aliases: 127 | 128 | Required: True 129 | Position: 0 130 | Default value: None 131 | Accept pipeline input: True (ByPropertyName, ByValue) 132 | Accept wildcard characters: False 133 | ``` 134 | 135 | ### -MessagePriority 136 | 137 | Parameter help description 138 | 139 | ```yaml 140 | Type: MessagePriority 141 | Parameter Sets: (All) 142 | Aliases: 143 | Accepted values: Normal, High, Emergency, Lowest, Low 144 | 145 | Required: False 146 | Position: Named 147 | Default value: None 148 | Accept pipeline input: False 149 | Accept wildcard characters: False 150 | ``` 151 | 152 | ### -RetryInterval 153 | 154 | Specifies the interval between emergency Pushover notifications. 155 | Pushover will retry until the message is acknowledged, or expired. 156 | Valid only with MessagePriority of 'Emergency'. 157 | 158 | ```yaml 159 | Type: TimeSpan 160 | Parameter Sets: (All) 161 | Aliases: 162 | 163 | Required: False 164 | Position: Named 165 | Default value: (New-TimeSpan -Minutes 1) 166 | Accept pipeline input: False 167 | Accept wildcard characters: False 168 | ``` 169 | 170 | ### -Sound 171 | 172 | Optionally specifies the notification sound to use 173 | 174 | ```yaml 175 | Type: String 176 | Parameter Sets: (All) 177 | Aliases: 178 | 179 | Required: False 180 | Position: Named 181 | Default value: None 182 | Accept pipeline input: False 183 | Accept wildcard characters: False 184 | ``` 185 | 186 | ### -Tags 187 | 188 | Optionally specifies one or more tags to associate with the Pushover notification. 189 | Tags can be used to cancel emergency notifications in bulk. 190 | 191 | ```yaml 192 | Type: String[] 193 | Parameter Sets: (All) 194 | Aliases: 195 | 196 | Required: False 197 | Position: Named 198 | Default value: None 199 | Accept pipeline input: False 200 | Accept wildcard characters: False 201 | ``` 202 | 203 | ### -Timestamp 204 | 205 | Optionally specifies the timestamp associated with the message. 206 | Default is DateTime.Now. 207 | 208 | ```yaml 209 | Type: DateTime 210 | Parameter Sets: (All) 211 | Aliases: 212 | 213 | Required: False 214 | Position: Named 215 | Default value: (Get-Date) 216 | Accept pipeline input: False 217 | Accept wildcard characters: False 218 | ``` 219 | 220 | ### -Title 221 | 222 | Specifies the title of the Pushover notification. 223 | The default will be the application name configured for the application API token supplied. 224 | 225 | ```yaml 226 | Type: String 227 | Parameter Sets: (All) 228 | Aliases: 229 | 230 | Required: False 231 | Position: Named 232 | Default value: None 233 | Accept pipeline input: False 234 | Accept wildcard characters: False 235 | ``` 236 | 237 | ### -Token 238 | 239 | Specifies the application API token/key from which the Pushover notification should be sent. 240 | Note: The default value will be used if it has been previously set with Set-PushoverConfig 241 | 242 | ```yaml 243 | Type: SecureString 244 | Parameter Sets: (All) 245 | Aliases: 246 | 247 | Required: False 248 | Position: Named 249 | Default value: None 250 | Accept pipeline input: False 251 | Accept wildcard characters: False 252 | ``` 253 | 254 | ### -Url 255 | 256 | Optionally specifies a supplementary URL associated with the message. 257 | 258 | ```yaml 259 | Type: Uri 260 | Parameter Sets: (All) 261 | Aliases: 262 | 263 | Required: False 264 | Position: Named 265 | Default value: None 266 | Accept pipeline input: False 267 | Accept wildcard characters: False 268 | ``` 269 | 270 | ### -UrlTitle 271 | 272 | Optionally specifies a title for the supplementary URL if specified. 273 | 274 | ```yaml 275 | Type: String 276 | Parameter Sets: (All) 277 | Aliases: 278 | 279 | Required: False 280 | Position: Named 281 | Default value: None 282 | Accept pipeline input: False 283 | Accept wildcard characters: False 284 | ``` 285 | 286 | ### -User 287 | 288 | Specifies the User or Group identifier to which the Pushover message should be sent. 289 | Note: The default value will be used if it has been previously set with Set-PushoverConfig 290 | 291 | ```yaml 292 | Type: SecureString 293 | Parameter Sets: (All) 294 | Aliases: 295 | 296 | Required: False 297 | Position: Named 298 | Default value: None 299 | Accept pipeline input: False 300 | Accept wildcard characters: False 301 | ``` 302 | 303 | ### -ProgressAction 304 | 305 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 306 | 307 | ```yaml 308 | Type: ActionPreference 309 | Parameter Sets: (All) 310 | Aliases: proga 311 | 312 | Required: False 313 | Position: Named 314 | Default value: None 315 | Accept pipeline input: False 316 | Accept wildcard characters: False 317 | ``` 318 | 319 | ### CommonParameters 320 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 321 | 322 | ## INPUTS 323 | 324 | ## OUTPUTS 325 | 326 | ### String 327 | 328 | ## NOTES 329 | 330 | ## RELATED LINKS 331 | -------------------------------------------------------------------------------- /docs/en-US/Set-PushoverConfig.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Set-PushoverConfig/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Set-PushoverConfig 9 | 10 | ## SYNOPSIS 11 | 12 | Sets the Pushover configuration in the PSPushover module 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Set-PushoverConfig [-ApiUri ] [-Token ] [-User ] [-Temporary] 18 | [-ProgressAction ] [-WhatIf] [-Confirm] [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | 23 | The Pushover API URI can be modified for the purpose of test automation, and application 24 | and user tokens can be securely stored on disk so that you don't have to supply the tokens 25 | with every call to Send-Pushover in case you are always sending notifications from the same 26 | application and to the same user/group. 27 | 28 | The location of the configuration file depends on your operating system. On Windows the path is 29 | usually `C:\Users\\AppData\Roaming\joshooaj.PSPushover\config.xml` and on Linux the path may 30 | be `/home//.config/joshooaj.PSPushover/config.xml`. PSPushover determines the application 31 | data path using the command `[Environment]::GetFolderPath([System.Environment+SpecialFolder]::ApplicationData)` 32 | 33 | ## EXAMPLES 34 | 35 | ### EXAMPLE 1 36 | 37 | ```powershell 38 | Set-PushoverConfig -Token (Read-Host -AsSecureString) 39 | Set-PushoverConfig -User (Read-Host -AsSecureString) 40 | ``` 41 | 42 | Prompts for the desired default application token and user token and persists it to disk to use as the default application and user tokens. 43 | 44 | ### EXAMPLE 2 45 | 46 | ```powershell 47 | Set-PushoverConfig -ApiUri http://localhost:8888 -Temporary 48 | ``` 49 | 50 | Sets the Pushover API URI to `http://localhost:8888` for the duration of the PowerShell session 51 | or until the PSPushover module is forcefully imported again. 52 | 53 | ## PARAMETERS 54 | 55 | ### -ApiUri 56 | 57 | Species the base URI to which all HTTP requests should be sent. 58 | Recommended to change this only for the purposes of test automation. 59 | 60 | ```yaml 61 | Type: Uri 62 | Parameter Sets: (All) 63 | Aliases: 64 | 65 | Required: False 66 | Position: Named 67 | Default value: None 68 | Accept pipeline input: False 69 | Accept wildcard characters: False 70 | ``` 71 | 72 | ### -Confirm 73 | Prompts you for confirmation before running the cmdlet. 74 | 75 | ```yaml 76 | Type: SwitchParameter 77 | Parameter Sets: (All) 78 | Aliases: cf 79 | 80 | Required: False 81 | Position: Named 82 | Default value: None 83 | Accept pipeline input: False 84 | Accept wildcard characters: False 85 | ``` 86 | 87 | ### -Temporary 88 | 89 | Specifies that the new settings should only be temporary and should not be saved to disk. The next time the PSPushover 90 | module is imported, the temporary value will be lost and the default values will be loaded from disk. 91 | 92 | ```yaml 93 | Type: SwitchParameter 94 | Parameter Sets: (All) 95 | Aliases: 96 | 97 | Required: False 98 | Position: Named 99 | Default value: False 100 | Accept pipeline input: False 101 | Accept wildcard characters: False 102 | ``` 103 | 104 | ### -Token 105 | 106 | The default application token to use when the token isn't otherwise specified. 107 | 108 | ```yaml 109 | Type: SecureString 110 | Parameter Sets: (All) 111 | Aliases: 112 | 113 | Required: False 114 | Position: Named 115 | Default value: None 116 | Accept pipeline input: False 117 | Accept wildcard characters: False 118 | ``` 119 | 120 | ### -User 121 | 122 | The default user or group token to use when the token isn't otherwise specified. 123 | 124 | ```yaml 125 | Type: SecureString 126 | Parameter Sets: (All) 127 | Aliases: 128 | 129 | Required: False 130 | Position: Named 131 | Default value: None 132 | Accept pipeline input: False 133 | Accept wildcard characters: False 134 | ``` 135 | 136 | ### -WhatIf 137 | Shows what would happen if the cmdlet runs. 138 | The cmdlet is not run. 139 | 140 | ```yaml 141 | Type: SwitchParameter 142 | Parameter Sets: (All) 143 | Aliases: wi 144 | 145 | Required: False 146 | Position: Named 147 | Default value: None 148 | Accept pipeline input: False 149 | Accept wildcard characters: False 150 | ``` 151 | 152 | ### -ProgressAction 153 | 154 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 155 | 156 | ```yaml 157 | Type: ActionPreference 158 | Parameter Sets: (All) 159 | Aliases: proga 160 | 161 | Required: False 162 | Position: Named 163 | Default value: None 164 | Accept pipeline input: False 165 | Accept wildcard characters: False 166 | ``` 167 | 168 | ### CommonParameters 169 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 170 | 171 | ## INPUTS 172 | 173 | ## OUTPUTS 174 | 175 | ## NOTES 176 | 177 | ## RELATED LINKS 178 | -------------------------------------------------------------------------------- /docs/en-US/Test-PushoverUser.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Test-PushoverUser/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Test-PushoverUser 9 | 10 | ## SYNOPSIS 11 | 12 | Validate a user token and optional device name against the Pushover API. 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Test-PushoverUser [[-Token] ] [[-User] ] [[-Device] ] 18 | [[-InformationLevel] ] [-ProgressAction ] [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | 23 | If you are collecting user tokens to register them to receive notifications, you may want to verify 24 | that the key is valid before accepting it. Use the `Test-PushoverUser` cmdlet to ensure user tokens 25 | are valid before sending notifications. 26 | 27 | The information returned is detailed by default and includes the error text returned from the 28 | Pushover API. For example, the error message may read "device name is not valid for user". 29 | 30 | ## EXAMPLES 31 | 32 | ### EXAMPLE 1 33 | 34 | ```powershell 35 | if ($null -eq (Get-PushoverConfig).AppToken) { 36 | Set-PushoverConfig -Token (Read-Host -Prompt 'Pushover Application Token' -AsSecureString) 37 | } 38 | Test-PushoverUser -User (Read-Host -Prompt 'Pushover User Key' -AsSecureString) 39 | 40 | <# Sample output 41 | Valid : False 42 | IsGroup : False 43 | Devices : 44 | Licenses : 45 | Error : user key is invalid 46 | #> 47 | ``` 48 | 49 | Checks whether the current user's Pushover config includes a default application token. If not, request the user to enter the application token 50 | and save it for future use. Then request the Pushover user key and test whether the key is valid. 51 | 52 | ## PARAMETERS 53 | 54 | ### -Device 55 | 56 | Optionally specifies the device on the user account to validate 57 | 58 | ```yaml 59 | Type: String 60 | Parameter Sets: (All) 61 | Aliases: 62 | 63 | Required: False 64 | Position: 2 65 | Default value: None 66 | Accept pipeline input: False 67 | Accept wildcard characters: False 68 | ``` 69 | 70 | ### -InformationLevel 71 | 72 | Specifies the information level desired in the response. 73 | Quiet means a boolean will be returned while Detailed will return an object with more information. 74 | 75 | ```yaml 76 | Type: PSPushoverInformationLevel 77 | Parameter Sets: (All) 78 | Aliases: 79 | Accepted values: Detailed, Quiet 80 | 81 | Required: False 82 | Position: 3 83 | Default value: Detailed 84 | Accept pipeline input: False 85 | Accept wildcard characters: False 86 | ``` 87 | 88 | ### -Token 89 | 90 | Specifies the application API token/key from which the Pushover notification should be sent. 91 | Note: The default value will be used if it has been previously set with Set-PushoverConfig 92 | 93 | ```yaml 94 | Type: SecureString 95 | Parameter Sets: (All) 96 | Aliases: 97 | 98 | Required: False 99 | Position: 0 100 | Default value: None 101 | Accept pipeline input: False 102 | Accept wildcard characters: False 103 | ``` 104 | 105 | ### -User 106 | 107 | Specifies the User or Group identifier to which the Pushover message should be sent. 108 | Note: The default value will be used if it has been previously set with Set-PushoverConfig 109 | 110 | ```yaml 111 | Type: SecureString 112 | Parameter Sets: (All) 113 | Aliases: 114 | 115 | Required: False 116 | Position: 1 117 | Default value: None 118 | Accept pipeline input: False 119 | Accept wildcard characters: False 120 | ``` 121 | 122 | ### -ProgressAction 123 | 124 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 125 | 126 | ```yaml 127 | Type: ActionPreference 128 | Parameter Sets: (All) 129 | Aliases: proga 130 | 131 | Required: False 132 | Position: Named 133 | Default value: None 134 | Accept pipeline input: False 135 | Accept wildcard characters: False 136 | ``` 137 | 138 | ### CommonParameters 139 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 140 | 141 | ## INPUTS 142 | 143 | ## OUTPUTS 144 | 145 | ### PSPushoverUserValidation 146 | 147 | ## NOTES 148 | 149 | ## RELATED LINKS 150 | -------------------------------------------------------------------------------- /docs/en-US/Wait-Pushover.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: joshooaj.PSPushover-help.xml 3 | Module Name: joshooaj.PSPushover 4 | online version: https://www.joshooaj.com/PSPushover/en-US/Wait-Pushover/ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Wait-Pushover 9 | 10 | ## SYNOPSIS 11 | 12 | Waits for a user to acknowledge receipt of the Pushover message or for the notification to expire. 13 | 14 | ## SYNTAX 15 | 16 | ``` 17 | Wait-Pushover [[-Token] ] [-Receipt] [[-Interval] ] 18 | [-ProgressAction ] [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | 23 | Waits for a user to acknowledge receipt of the Pushover message or for the notification to expire 24 | then returns the last `[PSPushoverNotificationStatus]` response object. 25 | 26 | ## EXAMPLES 27 | 28 | ### EXAMPLE 1 29 | 30 | ```powershell 31 | Send-Pushover -Message 'Please clap' -MessagePriority Emergency | Wait-Pushover 32 | ``` 33 | 34 | Sends an emergency Pushover notification and then waits for the notification to expire or for at least one user to acknowledge it. 35 | 36 | ## PARAMETERS 37 | 38 | ### -Interval 39 | 40 | Specifies the interval between each Pushover API request for receipt status 41 | 42 | ```yaml 43 | Type: Int32 44 | Parameter Sets: (All) 45 | Aliases: 46 | 47 | Required: False 48 | Position: 2 49 | Default value: 10 50 | Accept pipeline input: False 51 | Accept wildcard characters: False 52 | ``` 53 | 54 | ### -Receipt 55 | 56 | Specifies the receipt received from emergency notifications sent using Send-Pushover 57 | 58 | ```yaml 59 | Type: String 60 | Parameter Sets: (All) 61 | Aliases: 62 | 63 | Required: True 64 | Position: 1 65 | Default value: None 66 | Accept pipeline input: True (ByValue) 67 | Accept wildcard characters: False 68 | ``` 69 | 70 | ### -Token 71 | 72 | Specifies the Pushover application API token/key. 73 | Note: The default value will be used if it has been previously set with Set-PushoverConfig 74 | 75 | ```yaml 76 | Type: SecureString 77 | Parameter Sets: (All) 78 | Aliases: 79 | 80 | Required: False 81 | Position: 0 82 | Default value: None 83 | Accept pipeline input: False 84 | Accept wildcard characters: False 85 | ``` 86 | 87 | ### -ProgressAction 88 | 89 | Ignore this common parameter. PlatyPS is undergoing a rewrite and the current version does not recognize ProgressAction as a common parameter. 90 | 91 | ```yaml 92 | Type: ActionPreference 93 | Parameter Sets: (All) 94 | Aliases: proga 95 | 96 | Required: False 97 | Position: Named 98 | Default value: None 99 | Accept pipeline input: False 100 | Accept wildcard characters: False 101 | ``` 102 | 103 | ### CommonParameters 104 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 105 | 106 | ## INPUTS 107 | 108 | ## OUTPUTS 109 | 110 | ### PSPushoverNotificationStatus 111 | 112 | ## NOTES 113 | 114 | ## RELATED LINKS 115 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Classes/MessagePriority.ps1: -------------------------------------------------------------------------------- 1 | enum MessagePriority { 2 | Lowest = -2 3 | Low = -1 4 | Normal = 0 5 | High = 1 6 | Emergency = 2 7 | } -------------------------------------------------------------------------------- /joshooaj.PSPushover/Classes/PSPushoverInformationLevel.ps1: -------------------------------------------------------------------------------- 1 | enum PSPushoverInformationLevel { 2 | Detailed 3 | Quiet 4 | } 5 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Classes/PSPushoverNotificationStatus.ps1: -------------------------------------------------------------------------------- 1 | class PSPushoverNotificationStatus { 2 | [string]$Receipt 3 | [bool]$Acknowledged 4 | [datetime]$AcknowledgedAt 5 | [string]$AcknowledgedBy 6 | [string]$AcknowledgedByDevice 7 | [datetime]$LastDeliveredAt 8 | [bool]$Expired 9 | [datetime]$ExpiresAt 10 | [bool]$CalledBack 11 | [datetime]$CalledBackAt 12 | } 13 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Classes/PSPushoverUserValidation.ps1: -------------------------------------------------------------------------------- 1 | class PSPushoverUserValidation { 2 | [bool]$Valid 3 | [bool]$IsGroup 4 | [string[]]$Devices 5 | [string[]]$Licenses 6 | [string]$Error 7 | } 8 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Private/ConvertTo-PlainText.ps1: -------------------------------------------------------------------------------- 1 | function ConvertTo-PlainText { 2 | [CmdletBinding()] 3 | param ( 4 | # Specifies a securestring value to decrypt back to a plain text string 5 | [Parameter(Mandatory, ValueFromPipeline)] 6 | [securestring] 7 | $Value 8 | ) 9 | 10 | process { 11 | ([pscredential]::new('unused', $Value)).GetNetworkCredential().Password 12 | } 13 | } -------------------------------------------------------------------------------- /joshooaj.PSPushover/Private/Import-PushoverConfig.ps1: -------------------------------------------------------------------------------- 1 | function Import-PushoverConfig { 2 | <# 3 | .SYNOPSIS 4 | Imports the configuration including default API URI's and tokens 5 | .DESCRIPTION 6 | If the module has been previously used, the configuration should be present. If the config 7 | can be imported, the function returns true. Otherwise it returns false. 8 | #> 9 | [CmdletBinding()] 10 | [OutputType([bool])] 11 | param () 12 | 13 | process { 14 | if (Test-Path -Path $script:configPath) { 15 | try { 16 | Write-Verbose "Importing configuration from '$($script:configPath)'" 17 | $script:config = Import-Clixml -Path $script:configPath 18 | return $true 19 | } 20 | catch { 21 | Write-Error "Failed to import configuration from '$script:configPath'." -Exception $_.Exception 22 | } 23 | } 24 | else { 25 | Write-Verbose "No existing module configuration found at '$($script:configPath)'" 26 | } 27 | $false 28 | } 29 | } -------------------------------------------------------------------------------- /joshooaj.PSPushover/Private/Save-PushoverConfig.ps1: -------------------------------------------------------------------------------- 1 | function Save-PushoverConfig { 2 | <# 3 | .SYNOPSIS 4 | Save module configuration to disk 5 | #> 6 | [CmdletBinding()] 7 | param () 8 | 9 | process { 10 | Write-Verbose "Saving the module configuration to '$($script:configPath)'" 11 | $directory = ([io.fileinfo]$script:configPath).DirectoryName 12 | if (-not (Test-Path -Path $directory)) { 13 | $null = New-Item -Path $directory -ItemType Directory -Force 14 | } 15 | $script:config | Export-Clixml -Path $script:configPath -Force 16 | } 17 | } -------------------------------------------------------------------------------- /joshooaj.PSPushover/Private/Send-MessageWithAttachment.ps1: -------------------------------------------------------------------------------- 1 | function Send-MessageWithAttachment { 2 | <# 3 | .SYNOPSIS 4 | Sends an HTTP POST to the Pushover API using an HttpClient 5 | .DESCRIPTION 6 | When sending an image attachment with a Pushover message, you must use multipart/form-data 7 | and there doesn't seem to be a nice way to do this using Invoke-RestMethod like we're doing 8 | in the public Send-Message function. So when an attachment is provided to Send-Message, the 9 | body hashtable is constructed, and then sent over to this function to keep the main 10 | Send-Message function a manageable size. 11 | #> 12 | [CmdletBinding()] 13 | param ( 14 | # Specifies the various parameters and values expected by the Pushover messages api. 15 | [Parameter(Mandatory)] 16 | [hashtable] 17 | $Body, 18 | 19 | # Specifies the image to attach to the message as a byte array 20 | [Parameter(Mandatory)] 21 | [byte[]] 22 | $Attachment, 23 | 24 | # Optionally specifies a file name to associate with the attachment 25 | [Parameter()] 26 | [string] 27 | $FileName = 'attachment.jpg' 28 | ) 29 | 30 | begin { 31 | $uri = $script:PushoverApiUri + '/messages.json' 32 | } 33 | 34 | process { 35 | try { 36 | $client = [system.net.http.httpclient]::new() 37 | try { 38 | $content = [system.net.http.multipartformdatacontent]::new() 39 | foreach ($key in $Body.Keys) { 40 | $textContent = [system.net.http.stringcontent]::new($Body.$key) 41 | $content.Add($textContent, $key) 42 | } 43 | $jpegContent = [system.net.http.bytearraycontent]::new($Attachment) 44 | $jpegContent.Headers.ContentType = [system.net.http.headers.mediatypeheadervalue]::new('image/jpeg') 45 | $jpegContent.Headers.ContentDisposition = [system.net.http.headers.contentdispositionheadervalue]::new('form-data') 46 | $jpegContent.Headers.ContentDisposition.Name = 'attachment' 47 | $jpegContent.Headers.ContentDisposition.FileName = $FileName 48 | $content.Add($jpegContent) 49 | 50 | Write-Verbose "Message body:`r`n$($content.ReadAsStringAsync().Result.Substring(0, 2000).Replace($Body.token, "********").Replace($Body.user, "********"))" 51 | $result = $client.PostAsync($uri, $content).Result 52 | Write-Output ($result.Content.ReadAsStringAsync().Result | ConvertFrom-Json) 53 | } 54 | finally { 55 | $content.Dispose() 56 | } 57 | } 58 | finally { 59 | $client.Dispose() 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Get-PushoverConfig.ps1: -------------------------------------------------------------------------------- 1 | function Get-PushoverConfig { 2 | [CmdletBinding()] 3 | param () 4 | 5 | process { 6 | [pscustomobject]@{ 7 | PSTypeName = 'PushoverConfig' 8 | ApiUri = $script:config.PushoverApiUri 9 | AppToken = $script:config.DefaultAppToken 10 | UserToken = $script:config.DefaultUserToken 11 | ConfigPath = $script:configPath 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Get-PushoverSound.ps1: -------------------------------------------------------------------------------- 1 | function Get-PushoverSound { 2 | [CmdletBinding()] 3 | [OutputType([hashtable])] 4 | param ( 5 | [Parameter()] 6 | [ValidateNotNullOrEmpty()] 7 | [securestring] 8 | $Token 9 | ) 10 | 11 | begin { 12 | $config = Get-PushoverConfig 13 | $uriBuilder = [uribuilder]($config.ApiUri + '/sounds.json') 14 | } 15 | 16 | process { 17 | if ($null -eq $Token) { 18 | $Token = $config.AppToken 19 | if ($null -eq $Token) { 20 | throw "Token not provided and no default application token has been set using Set-PushoverConfig." 21 | } 22 | } 23 | 24 | try { 25 | $uriBuilder.Query = "token=" + ($Token | ConvertTo-PlainText) 26 | $response = Invoke-RestMethod -Method Get -Uri $uriBuilder.Uri 27 | } 28 | catch { 29 | Write-Verbose 'Handling HTTP error in Invoke-RestMethod response' 30 | $statusCode = $_.Exception.Response.StatusCode.value__ 31 | Write-Verbose "HTTP status code $statusCode" 32 | if ($statusCode -lt 400 -or $statusCode -gt 499) { 33 | throw 34 | } 35 | 36 | try { 37 | Write-Verbose 'Parsing HTTP request error response' 38 | $stream = $_.Exception.Response.GetResponseStream() 39 | $reader = [io.streamreader]::new($stream) 40 | $response = $reader.ReadToEnd() | ConvertFrom-Json 41 | if ([string]::IsNullOrWhiteSpace($response)) { 42 | throw $_ 43 | } 44 | Write-Verbose "Response body:`r`n$response" 45 | } 46 | finally { 47 | $reader.Dispose() 48 | } 49 | } 50 | 51 | if ($response.status -eq 1) { 52 | $sounds = @{} 53 | foreach ($name in $response.sounds | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name) { 54 | $sounds.$name = $response.sounds.$name 55 | } 56 | Write-Output $sounds 57 | } 58 | else { 59 | if ($null -ne $response.error) { 60 | Write-Error $response.error 61 | } 62 | elseif ($null -ne $response.errors) { 63 | foreach ($problem in $response.errors) { 64 | Write-Error $problem 65 | } 66 | } 67 | else { 68 | $response 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Get-PushoverStatus.ps1: -------------------------------------------------------------------------------- 1 | function Get-PushoverStatus { 2 | [CmdletBinding()] 3 | [OutputType([PSPushoverNotificationStatus])] 4 | param ( 5 | [Parameter()] 6 | [ValidateNotNullOrEmpty()] 7 | [securestring] 8 | $Token, 9 | 10 | [Parameter(Mandatory, ValueFromPipeline)] 11 | [string] 12 | $Receipt 13 | ) 14 | 15 | begin { 16 | $config = Get-PushoverConfig 17 | $uriBuilder = [uribuilder]($config.ApiUri + '/receipts') 18 | } 19 | 20 | process { 21 | if ($null -eq $Token) { 22 | $Token = $config.AppToken 23 | if ($null -eq $Token) { 24 | throw "Token not provided and no default application token has been set using Set-PushoverConfig." 25 | } 26 | } 27 | $uriBuilder.Path += "/$Receipt.json" 28 | $uriBuilder.Query = "token=" + ($Token | ConvertTo-PlainText) 29 | try { 30 | $uriBuilder.Query = "token=" + ($Token | ConvertTo-PlainText) 31 | $response = Invoke-RestMethod -Method Get -Uri $uriBuilder.Uri 32 | } 33 | catch { 34 | Write-Verbose 'Handling HTTP error in Invoke-RestMethod response' 35 | $statusCode = $_.Exception.Response.StatusCode.value__ 36 | Write-Verbose "HTTP status code $statusCode" 37 | if ($statusCode -lt 400 -or $statusCode -gt 499) { 38 | throw 39 | } 40 | 41 | try { 42 | Write-Verbose 'Parsing HTTP request error response' 43 | $stream = $_.Exception.Response.GetResponseStream() 44 | $reader = [io.streamreader]::new($stream) 45 | $response = $reader.ReadToEnd() | ConvertFrom-Json 46 | if ([string]::IsNullOrWhiteSpace($response)) { 47 | throw $_ 48 | } 49 | Write-Verbose "Response body:`r`n$response" 50 | } 51 | finally { 52 | $reader.Dispose() 53 | } 54 | } 55 | 56 | if ($response.status -eq 1) { 57 | [PSPushoverNotificationStatus]@{ 58 | Receipt = $Receipt 59 | Acknowledged = [bool]$response.acknowledged 60 | AcknowledgedAt = [datetimeoffset]::FromUnixTimeSeconds($response.acknowledged_at).DateTime.ToLocalTime() 61 | AcknowledgedBy = $response.acknowledged_by 62 | AcknowledgedByDevice = $response.acknowledged_by_device 63 | LastDeliveredAt = [datetimeoffset]::FromUnixTimeSeconds($response.last_delivered_at).DateTime.ToLocalTime() 64 | Expired = [bool]$response.expired 65 | ExpiresAt = [datetimeoffset]::FromUnixTimeSeconds($response.expires_at).DateTime.ToLocalTime() 66 | CalledBack = [bool]$response.called_back 67 | CalledBackAt = [datetimeoffset]::FromUnixTimeSeconds($response.called_back_at).DateTime.ToLocalTime() 68 | } 69 | } 70 | else { 71 | if ($null -ne $response.error) { 72 | Write-Error $response.error 73 | } 74 | elseif ($null -ne $response.errors) { 75 | foreach ($problem in $response.errors) { 76 | Write-Error $problem 77 | } 78 | } 79 | else { 80 | $response 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Reset-PushoverConfig.ps1: -------------------------------------------------------------------------------- 1 | function Reset-PushoverConfig { 2 | [CmdletBinding(SupportsShouldProcess)] 3 | param () 4 | 5 | process { 6 | if ($PSCmdlet.ShouldProcess("PSPushover Module Configuration", "Reset to default")) { 7 | Write-Verbose "Using the default module configuration" 8 | $script:config = @{ 9 | PushoverApiDefaultUri = 'https://api.pushover.net/1' 10 | PushoverApiUri = 'https://api.pushover.net/1' 11 | DefaultAppToken = $null 12 | DefaultUserToken = $null 13 | } 14 | Save-PushoverConfig 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Send-Pushover.ps1: -------------------------------------------------------------------------------- 1 | function Send-Pushover { 2 | [CmdletBinding()] 3 | [OutputType([string])] 4 | param ( 5 | [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] 6 | [ValidateNotNullOrEmpty()] 7 | [string] 8 | $Message, 9 | 10 | [Parameter()] 11 | [string] 12 | $Title, 13 | 14 | [Parameter()] 15 | [byte[]] 16 | $Attachment, 17 | 18 | [Parameter()] 19 | [string] 20 | $FileName = 'attachment.jpg', 21 | 22 | [Parameter()] 23 | [ValidateNotNullOrEmpty()] 24 | [uri] 25 | $Url, 26 | 27 | [Parameter()] 28 | [ValidateNotNullOrEmpty()] 29 | [string] 30 | $UrlTitle, 31 | 32 | [Parameter()] 33 | [MessagePriority] 34 | $MessagePriority, 35 | 36 | [Parameter()] 37 | [ValidateScript({ 38 | if ($_.TotalSeconds -lt 30) { 39 | throw 'RetryInterval must be at least 30 seconds' 40 | } 41 | if ($_.TotalSeconds -gt 10800) { 42 | throw 'RetryInterval cannot exceed 3 hours' 43 | } 44 | $true 45 | })] 46 | [timespan] 47 | $RetryInterval = (New-TimeSpan -Minutes 1), 48 | 49 | [Parameter()] 50 | [ValidateScript({ 51 | if ($_.TotalSeconds -le 30) { 52 | throw 'ExpireAfter must be greater than the minimum RetryInterval value of 30 seconds' 53 | } 54 | if ($_.TotalSeconds -gt 10800) { 55 | throw 'ExpireAfter cannot exceed 3 hours' 56 | } 57 | $true 58 | })] 59 | [timespan] 60 | $ExpireAfter = (New-TimeSpan -Minutes 10), 61 | 62 | [Parameter()] 63 | [datetime] 64 | $Timestamp = (Get-Date), 65 | 66 | [Parameter()] 67 | [ValidateNotNullOrEmpty()] 68 | [string] 69 | $Sound, 70 | 71 | [Parameter()] 72 | [string[]] 73 | $Tags, 74 | 75 | [Parameter()] 76 | [ValidateNotNullOrEmpty()] 77 | [securestring] 78 | $Token, 79 | 80 | [Parameter()] 81 | [ValidateNotNullOrEmpty()] 82 | [securestring] 83 | $User, 84 | 85 | [Parameter()] 86 | [ValidateNotNullOrEmpty()] 87 | [string[]] 88 | $Device 89 | ) 90 | 91 | begin { 92 | $config = Get-PushoverConfig 93 | $uri = $config.ApiUri + '/messages.json' 94 | } 95 | 96 | process { 97 | if ($null -eq $Token) { 98 | $Token = $config.AppToken 99 | if ($null -eq $Token) { 100 | throw "Token not provided and no default application token has been set using Set-PushoverConfig." 101 | } 102 | } 103 | if ($null -eq $User) { 104 | $User = $config.UserToken 105 | if ($null -eq $User) { 106 | throw "User not provided and no default user id has been set using Set-PushoverConfig." 107 | } 108 | } 109 | 110 | $deviceList = if ($null -ne $Device) { 111 | [string]::Join(',', $Device) 112 | } else { $null } 113 | 114 | $tagList = if ($null -ne $Tags) { 115 | [string]::Join(',', $Tags) 116 | } else { $null } 117 | 118 | $body = [ordered]@{ 119 | token = $Token | ConvertTo-PlainText 120 | user = $User | ConvertTo-PlainText 121 | device = $deviceList 122 | title = $Title 123 | message = $Message 124 | url = $Url 125 | url_title = $UrlTitle 126 | priority = [int]$MessagePriority 127 | retry = [int]$RetryInterval.TotalSeconds 128 | expire = [int]$ExpireAfter.TotalSeconds 129 | timestamp = [int]([datetimeoffset]::new($Timestamp).ToUnixTimeMilliseconds() / 1000) 130 | tags = $tagList 131 | sound = $Sound 132 | } 133 | 134 | try { 135 | if ($Attachment.Length -eq 0) { 136 | $bodyJson = $body | ConvertTo-Json 137 | Write-Verbose "Message body:`r`n$($bodyJson.Replace($Body.token, "********").Replace($Body.user, "********"))" 138 | $response = Invoke-RestMethod -Method Post -Uri $uri -Body $bodyJson -ContentType application/json -UseBasicParsing 139 | } else { 140 | $response = Send-MessageWithAttachment -Body $body -Attachment $Attachment -FileName $FileName 141 | } 142 | } catch { 143 | Write-Verbose 'Handling HTTP error in Invoke-RestMethod response' 144 | $statusCode = $_.Exception.Response.StatusCode.value__ 145 | Write-Verbose "HTTP status code $statusCode" 146 | if ($statusCode -lt 400 -or $statusCode -gt 499) { 147 | throw 148 | } 149 | 150 | try { 151 | Write-Verbose 'Parsing HTTP request error response' 152 | $stream = $_.Exception.Response.GetResponseStream() 153 | $reader = [io.streamreader]::new($stream) 154 | $response = $reader.ReadToEnd() | ConvertFrom-Json 155 | if ([string]::IsNullOrWhiteSpace($response)) { 156 | throw $_ 157 | } 158 | Write-Verbose "Response body:`r`n$response" 159 | } finally { 160 | $reader.Dispose() 161 | } 162 | } 163 | 164 | if ($response.status -ne 1) { 165 | if ($null -ne $response.error) { 166 | Write-Error $response.error 167 | } elseif ($null -ne $response.errors) { 168 | foreach ($problem in $response.errors) { 169 | Write-Error $problem 170 | } 171 | } else { 172 | $response 173 | } 174 | } 175 | 176 | if ($null -ne $response.receipt) { 177 | Write-Output $response.receipt 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Set-PushoverConfig.ps1: -------------------------------------------------------------------------------- 1 | function Set-PushoverConfig { 2 | [CmdletBinding(SupportsShouldProcess)] 3 | param ( 4 | [Parameter()] 5 | [uri] 6 | $ApiUri, 7 | 8 | [Parameter(ParameterSetName = 'AsPlainText')] 9 | [securestring] 10 | $Token, 11 | 12 | [Parameter()] 13 | [securestring] 14 | $User, 15 | 16 | [Parameter()] 17 | [switch] 18 | $Temporary 19 | ) 20 | 21 | process { 22 | if ($PSBoundParameters.ContainsKey('ApiUri')) { 23 | if ($PSCmdlet.ShouldProcess("Pushover ApiUri", "Set value to '$ApiUri'")) { 24 | $script:config.PushoverAPiUri = $ApiUri.ToString() 25 | } 26 | } 27 | if ($PSBoundParameters.ContainsKey('Token')) { 28 | if ($PSCmdlet.ShouldProcess("Pushover Default Application Token", "Set value")) { 29 | $script:config.DefaultAppToken = $Token 30 | } 31 | } 32 | if ($PSBoundParameters.ContainsKey('User')) { 33 | if ($PSCmdlet.ShouldProcess("Pushover Default User Key", "Set value")) { 34 | $script:config.DefaultUserToken = $User 35 | } 36 | } 37 | 38 | if (-not $Temporary) { 39 | Save-PushoverConfig 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Test-PushoverUser.ps1: -------------------------------------------------------------------------------- 1 | function Test-PushoverUser { 2 | [CmdletBinding()] 3 | [OutputType([PSPushoverUserValidation])] 4 | param ( 5 | [Parameter()] 6 | [ValidateNotNullOrEmpty()] 7 | [securestring] 8 | $Token, 9 | 10 | [Parameter()] 11 | [ValidateNotNullOrEmpty()] 12 | [securestring] 13 | $User, 14 | 15 | [Parameter()] 16 | [ValidateNotNullOrEmpty()] 17 | [string] 18 | $Device, 19 | 20 | [Parameter()] 21 | [PSPushoverInformationLevel] 22 | $InformationLevel = [PSPushoverInformationLevel]::Detailed 23 | ) 24 | 25 | begin { 26 | $config = Get-PushoverConfig 27 | $uri = $config.ApiUri + '/users/validate.json' 28 | } 29 | 30 | process { 31 | if ($null -eq $Token) { 32 | $Token = $config.AppToken 33 | if ($null -eq $Token) { 34 | throw "Token not provided and no default application token has been set using Set-PushoverConfig." 35 | } 36 | } 37 | if ($null -eq $User) { 38 | $User = $config.UserToken 39 | if ($null -eq $User) { 40 | throw "User not provided and no default user id has been set using Set-PushoverConfig." 41 | } 42 | } 43 | 44 | $body = [ordered]@{ 45 | token = $Token | ConvertTo-PlainText 46 | user = $User | ConvertTo-PlainText 47 | device = $Device 48 | } 49 | 50 | try { 51 | $bodyJson = $body | ConvertTo-Json 52 | Write-Verbose "Message body:`r`n$($bodyJson.Replace($Body.token, "********").Replace($Body.user, "********"))" 53 | if (Get-Command Invoke-RestMethod -ParameterName SkipHttpErrorCheck -ErrorAction SilentlyContinue) { 54 | $response = Invoke-RestMethod -Method Post -Uri $uri -Body $bodyJson -ContentType application/json -SkipHttpErrorCheck 55 | } else { 56 | $response = Invoke-RestMethod -Method Post -Uri $uri -Body $bodyJson -ContentType application/json -UseBasicParsing 57 | } 58 | 59 | } catch { 60 | Write-Verbose 'Handling HTTP error in Invoke-RestMethod response' 61 | $statusCode = $_.Exception.Response.StatusCode.value__ 62 | Write-Verbose "HTTP status code $statusCode" 63 | if ($statusCode -lt 400 -or $statusCode -gt 499) { 64 | throw 65 | } 66 | 67 | try { 68 | Write-Verbose 'Parsing HTTP request error response' 69 | $stream = $_.Exception.Response.GetResponseStream() 70 | $reader = [io.streamreader]::new($stream) 71 | $response = $reader.ReadToEnd() | ConvertFrom-Json 72 | if ([string]::IsNullOrWhiteSpace($response)) { 73 | throw $_ 74 | } 75 | Write-Verbose "Response body:`r`n$response" 76 | } finally { 77 | $reader.Dispose() 78 | } 79 | } 80 | 81 | if ($null -ne $response.status) { 82 | switch ($InformationLevel) { 83 | ([PSPushoverInformationLevel]::Quiet) { 84 | Write-Output ($response.status -eq 1) 85 | } 86 | 87 | ([PSPushoverInformationLevel]::Detailed) { 88 | [PSPushoverUserValidation]@{ 89 | Valid = $response.status -eq 1 90 | IsGroup = $response.group -eq 1 91 | Devices = $response.devices 92 | Licenses = $response.licenses 93 | Error = $response.errors | Select-Object -First 1 94 | } 95 | } 96 | Default { throw "InformationLevel $InformationLevel not implemented." } 97 | } 98 | } else { 99 | Write-Error "Unexpected response: $($response | ConvertTo-Json)" 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/Public/Wait-Pushover.ps1: -------------------------------------------------------------------------------- 1 | function Wait-Pushover { 2 | [CmdletBinding()] 3 | [OutputType([PSPushoverNotificationStatus])] 4 | param ( 5 | [Parameter()] 6 | [ValidateNotNullOrEmpty()] 7 | [securestring] 8 | $Token, 9 | 10 | [Parameter(Mandatory, ValueFromPipeline)] 11 | [string] 12 | $Receipt, 13 | 14 | [Parameter()] 15 | [ValidateRange(5, 10800)] 16 | [int] 17 | $Interval = 10 18 | ) 19 | 20 | begin { 21 | $config = Get-PushoverConfig 22 | } 23 | 24 | process { 25 | if ($null -eq $Token) { 26 | $Token = $config.Token 27 | if ($null -eq $Token) { 28 | throw "Token not provided and no default application token has been set using Set-PushoverConfig." 29 | } 30 | } 31 | 32 | $timeoutAt = (Get-Date).AddHours(3) 33 | while ((Get-Date) -lt $timeoutAt.AddSeconds($Interval)) { 34 | $status = Get-PushoverStatus -Token $Token -Receipt $Receipt -ErrorAction Stop 35 | $timeoutAt = $status.ExpiresAt 36 | if ($status.Acknowledged -or $status.Expired) { 37 | break 38 | } 39 | Start-Sleep -Seconds $Interval 40 | } 41 | Write-Output $status 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/joshooaj.PSPushover.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | RootModule = 'joshooaj.PSPushover.psm1' 3 | # ModuleVersion is updated in the output directory using a PostAction on the StageFiles psake task. The version number is provided by nbgv. 4 | ModuleVersion = '0.1.0' 5 | GUID = '4db4b678-dc3f-47b1-bfe0-4ffc65ae03f4' 6 | Author = 'joshooaj' 7 | CompanyName = 'joshooaj' 8 | Copyright = '(c) Joshua Hendricks. All rights reserved.' 9 | Description = 'Send notifications to any device from PowerShell using pushover.net.' 10 | # FunctionsToExport is updated in the output directory by PowerShellBuild 11 | FunctionsToExport = '*' 12 | CmdletsToExport = @() 13 | VariablesToExport = @() 14 | AliasesToExport = @() 15 | PrivateData = @{ 16 | PSData = @{ 17 | Tags = @('notifications', 'pushover') 18 | LicenseUri = 'https://github.com/joshooaj/PSPushover/blob/main/LICENSE' 19 | ProjectUri = 'https://github.com/joshooaj/PSPushover' 20 | # IconUri = '' 21 | # ReleaseNotes = '' 22 | # Prerelease = '' 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /joshooaj.PSPushover/joshooaj.PSPushover.psm1: -------------------------------------------------------------------------------- 1 | # Dot source public/private functions when importing from source 2 | if (Test-Path -Path $PSScriptRoot/Public) { 3 | $classes = @(Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Classes/*.ps1') -Recurse -ErrorAction Stop) 4 | $public = @(Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Public/*.ps1') -Recurse -ErrorAction Stop) 5 | $private = @(Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Private/*.ps1') -Recurse -ErrorAction Stop) 6 | foreach ($import in @(($classes + $public + $private))) { 7 | try { 8 | . $import.FullName 9 | } catch { 10 | throw "Unable to dot source [$($import.FullName)]" 11 | } 12 | } 13 | 14 | Export-ModuleMember -Function $public.Basename 15 | } 16 | 17 | $script:PushoverApiDefaultUri = 'https://api.pushover.net/1' 18 | $script:PushoverApiUri = $script:PushoverApiDefaultUri 19 | 20 | $appDataRoot = [environment]::GetFolderPath([System.Environment+SpecialFolder]::ApplicationData) 21 | $script:configPath = Join-Path $appDataRoot 'joshooaj.PSPushover\config.xml' 22 | $script:config = $null 23 | if (-not (Import-PushoverConfig)) { 24 | Reset-PushoverConfig 25 | } 26 | 27 | $soundsCompleter = { 28 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) 29 | 30 | $soundList = @('incoming', 'pianobar', 'climb', 'gamelan', 'bugle', 'vibrate', 'pushover', 'cosmic', 'spacealarm', 'updown', 'none', 'persistent', 'cashregister', 'mechanical', 'bike', 'classical', 'falling', 'alien', 'magic', 'siren', 'tugboat', 'intermission', 'echo') 31 | $soundList | Where-Object { 32 | $_ -like "$wordToComplete*" 33 | } | Foreach-Object { 34 | "'$_'" 35 | } 36 | } 37 | Register-ArgumentCompleter -CommandName Send-Pushover -ParameterName Sound -ScriptBlock $soundsCompleter 38 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: PSPushover 2 | site_description: Send notifications to any device from PowerShell using pushover.net 3 | site_dir: Output/site 4 | repo_url: https://github.com/joshooaj/PSPushover 5 | remote_branch: gh-pages 6 | 7 | theme: 8 | name: material 9 | logo: assets/images/joshooaj.png 10 | favicon: assets/images/joshooaj.png 11 | font: 12 | text: Roboto 13 | code: Roboto Mono 14 | icon: 15 | repo: material/github 16 | palette: 17 | # Palette toggle for automatic mode 18 | - media: "(prefers-color-scheme)" 19 | toggle: 20 | icon: material/brightness-auto 21 | name: Switch to light mode 22 | 23 | # Palette toggle for light mode 24 | - media: "(prefers-color-scheme: light)" 25 | scheme: default 26 | toggle: 27 | icon: material/brightness-7 28 | name: Switch to dark mode 29 | 30 | # Palette toggle for dark mode 31 | - media: "(prefers-color-scheme: dark)" 32 | scheme: slate 33 | toggle: 34 | icon: material/brightness-4 35 | name: Switch to system preference 36 | 37 | plugins: 38 | - search 39 | - awesome-pages 40 | - social: 41 | cards_layout_options: 42 | color: "#ffffff" 43 | background_color: "#4d9bea" 44 | 45 | markdown_extensions: 46 | - attr_list 47 | - admonition 48 | - md_in_html 49 | - pymdownx.emoji: 50 | emoji_index: !!python/name:material.extensions.emoji.twemoji 51 | emoji_generator: !!python/name:material.extensions.emoji.to_svg 52 | - pymdownx.highlight: 53 | linenums_style: pymdownx-inline 54 | anchor_linenums: true 55 | line_spans: __span 56 | pygments_lang_class: true 57 | - pymdownx.inlinehilite 58 | - pymdownx.superfences 59 | - pymdownx.tabbed: 60 | alternate_style: true 61 | combine_header_slug: true 62 | slugify: !!python/object/apply:pymdownx.slugs.slugify 63 | kwds: 64 | case: lower 65 | - pymdownx.tasklist: 66 | custom_checkbox: true 67 | 68 | extra: 69 | social: 70 | - icon: fontawesome/brands/twitter 71 | link: https://twitter.com/joshooaj 72 | name: joshooaj on Twitter 73 | - icon: fontawesome/brands/linkedin 74 | link: https://www.linkedin.com/in/joshooaj 75 | name: joshooaj on LinkedIn 76 | - icon: fontawesome/brands/github 77 | link: https://github.com/joshooaj 78 | name: joshooaj on GitHub 79 | 80 | nav: 81 | - Home: README.md 82 | - Commands: 83 | - ... | flat | en-US/*.md 84 | -------------------------------------------------------------------------------- /psakeFile.ps1: -------------------------------------------------------------------------------- 1 | properties { 2 | & dotnet tool restore 3 | # Set this to $true to create a module with a monolithic PSM1 4 | $PSBPreference.Build.CompileModule = $true 5 | $PSBPreference.Docs.RootDir = './docs' 6 | $PSBPreference.General.ModuleVersion = (dotnet nbgv get-version -f json | ConvertFrom-Json).SimpleVersion 7 | $PSBPreference.Help.DefaultLocale = 'en-US' 8 | $PSBPreference.Test.OutputFile = 'out/testResults.xml' 9 | $PSBPreference.Test.ScriptAnalysis.SettingsPath = Join-Path $psake.build_script_dir 'PSScriptAnalyzerSettings.psd1' 10 | $psake.context.tasks.stagefiles.PostAction = { 11 | $outputManifestPath = [io.path]::Combine($PSBPreference.Build.ModuleOutDir, "$($PSBPreference.General.ModuleName).psd1") 12 | Update-Metadata -Path $outputManifestPath -PropertyName ModuleVersion -Value $PSBPreference.General.ModuleVersion 13 | } 14 | } 15 | 16 | task Default -depends Test 17 | task Build -FromModule PowerShellBuild -minimumVersion '0.6.1' 18 | task Test -FromModule PowerShellBuild -minimumVersion '0.6.1' 19 | 20 | task Serve -depends Build { 21 | if ($null -eq (Get-Command mkdocs -ErrorAction SilentlyContinue)) { 22 | throw "Cannot find the 'mkdocs' command. Install python and mkdocs, or consider using the dev container." 23 | } 24 | exec { 25 | mkdocs serve -a 0.0.0.0:8000 26 | } 27 | } 28 | 29 | task PublishDocs -depends Build { 30 | exec { 31 | docker run -v "$($psake.build_script_dir)`:/docs" -e 'CI=true' --entrypoint 'sh' squidfunk/mkdocs-material:9 -c 'pip install -r requirements.txt && mkdocs gh-deploy --force' 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /requirements.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | PSDepend = @{ 3 | Version = '0.3.8' 4 | } 5 | PSDependOptions = @{ 6 | Target = 'CurrentUser' 7 | } 8 | 'Pester' = @{ 9 | Version = '5.5.0' 10 | Parameters = @{ 11 | SkipPublisherCheck = $true 12 | } 13 | } 14 | 'psake' = @{ 15 | Version = '4.9.0' 16 | } 17 | 'BuildHelpers' = @{ 18 | Version = '2.0.16' 19 | } 20 | 'PowerShellBuild' = @{ 21 | Version = '0.6.1' 22 | } 23 | 'PSScriptAnalyzer' = @{ 24 | Version = '1.21.0' 25 | } 26 | 'PythonRequirements' = @{ 27 | DependencyType = 'Command' 28 | Source = 'pip install -qr requirements.txt --cache-dir .cache/pip/' 29 | } 30 | 'DotnetCLI' = @{ 31 | DependencyType = 'DotnetSdk' 32 | Version = '8.0.200' 33 | Target = './.cache/dotnet/' 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # This file defines python requirements to be installed with pip. 2 | 3 | mkdocs~=1.5 4 | mkdocs-material~=9.5 5 | mkdocs-awesome-pages-plugin~=2.9 6 | -------------------------------------------------------------------------------- /tests/Help.tests.ps1: -------------------------------------------------------------------------------- 1 | # Taken with love from @juneb_get_help (https://raw.githubusercontent.com/juneb/PesterTDD/master/Module.Help.Tests.ps1) 2 | 3 | BeforeDiscovery { 4 | 5 | function global:FilterOutCommonParams { 6 | param ($Params) 7 | $commonParams = @( 8 | 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 9 | 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 10 | 'WarningVariable', 'Confirm', 'Whatif' 11 | ) 12 | $params | Where-Object { $_.Name -notin $commonParams } | Sort-Object -Property Name -Unique 13 | } 14 | 15 | $outputModVerManifest = Join-Path -Path $env:BHBuildOutput -ChildPath "$($env:BHProjectName).psd1" 16 | 17 | # Get module commands 18 | # Remove all versions of the module from the session. Pester can't handle multiple versions. 19 | Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore 20 | Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop 21 | $params = @{ 22 | Module = (Get-Module $env:BHProjectName) 23 | CommandType = [System.Management.Automation.CommandTypes[]]'Cmdlet, Function' # Not alias 24 | } 25 | if ($PSVersionTable.PSVersion.Major -lt 6) { 26 | $params.CommandType[0] += 'Workflow' 27 | } 28 | $commands = Get-Command @params 29 | 30 | ## When testing help, remember that help is cached at the beginning of each session. 31 | ## To test, restart session. 32 | } 33 | 34 | Describe "Test help for <_.Name>" -ForEach $commands { 35 | 36 | BeforeDiscovery { 37 | # Get command help, parameters, and links 38 | $command = $_ 39 | $commandHelp = Get-Help $command.Name -ErrorAction SilentlyContinue 40 | $commandParameters = global:FilterOutCommonParams -Params $command.ParameterSets.Parameters 41 | $commandParameterNames = $commandParameters.Name 42 | $helpLinks = $commandHelp.relatedLinks.navigationLink.uri 43 | } 44 | 45 | BeforeAll { 46 | # These vars are needed in both discovery and test phases so we need to duplicate them here 47 | $command = $_ 48 | $commandName = $_.Name 49 | $commandHelp = Get-Help $command.Name -ErrorAction SilentlyContinue 50 | $commandParameters = global:FilterOutCommonParams -Params $command.ParameterSets.Parameters 51 | $commandParameterNames = $commandParameters.Name 52 | $helpParameters = global:FilterOutCommonParams -Params $commandHelp.Parameters.Parameter 53 | $helpParameterNames = $helpParameters.Name 54 | } 55 | 56 | # If help is not found, synopsis in auto-generated help is the syntax diagram 57 | It 'Help is not auto-generated' { 58 | $commandHelp.Synopsis | Should -Not -BeLike '*`[``]*' 59 | } 60 | 61 | # Should be a description for every function 62 | It "Has description" { 63 | $commandHelp.Description | Should -Not -BeNullOrEmpty 64 | } 65 | 66 | # Should be at least one example 67 | It "Has example code" { 68 | ($commandHelp.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty 69 | } 70 | 71 | # Should be at least one example description 72 | It "Has example help" { 73 | ($commandHelp.Examples.Example.Remarks | Select-Object -First 1).Text | Should -Not -BeNullOrEmpty 74 | } 75 | 76 | It "Help link <_> is valid" -ForEach $helpLinks { 77 | (Invoke-WebRequest -Uri $_ -UseBasicParsing).StatusCode | Should -Be '200' 78 | } 79 | 80 | Context "Parameter <_.Name>" -Foreach $commandParameters { 81 | 82 | BeforeAll { 83 | $parameter = $_ 84 | $parameterName = $parameter.Name 85 | $parameterHelp = $commandHelp.parameters.parameter | Where-Object Name -eq $parameterName 86 | $parameterHelpType = if ($parameterHelp.ParameterValue) { $parameterHelp.ParameterValue.Trim() } 87 | } 88 | 89 | # Should be a description for every parameter 90 | It "Has description" { 91 | $parameterHelp.Description.Text | Should -Not -BeNullOrEmpty 92 | } 93 | 94 | # Required value in Help should match IsMandatory property of parameter 95 | It "Has correct [mandatory] value" { 96 | $codeMandatory = $_.IsMandatory.toString() 97 | $parameterHelp.Required | Should -Be $codeMandatory 98 | } 99 | 100 | # Parameter type in help should match code 101 | It "Has correct parameter type" { 102 | $parameterHelpType | Should -Be $parameter.ParameterType.Name 103 | } 104 | } 105 | 106 | Context "Test <_> help parameter help for " -Foreach $helpParameterNames { 107 | 108 | # Shouldn't find extra parameters in help. 109 | It "finds help parameter in code: <_>" { 110 | $_ -in $parameterNames | Should -Be $true 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /tests/Manifest.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | 3 | # NEW: Pre-Specify RegEx Matching Patterns 4 | $gitTagMatchRegEx = 'tag:\s?.(\d+(\.\d+)*)' # NOTE - was 'tag:\s*(\d+(?:\.\d+)*)' previously 5 | 6 | $moduleName = $env:BHProjectName 7 | $outputManifestPath = Join-Path -Path $env:BHBuildOutput -ChildPath "$($env:BHProjectName).psd1" 8 | $manifestData = Test-ModuleManifest -Path $outputManifestPath -Verbose:$false -ErrorAction Stop -WarningAction SilentlyContinue 9 | 10 | $script:manifest = $null 11 | } 12 | Describe 'Module manifest' { 13 | 14 | Context 'Validation' { 15 | 16 | It 'Has a valid manifest' { 17 | $manifestData | Should -Not -BeNullOrEmpty 18 | } 19 | 20 | It 'Has a valid name in the manifest' { 21 | $manifestData.Name | Should -Be $moduleName 22 | } 23 | 24 | It 'Has a valid root module' { 25 | $manifestData.RootModule | Should -Be "$($moduleName).psm1" 26 | } 27 | 28 | It 'Has a valid version in the manifest' { 29 | $manifestData.Version -as [Version] | Should -Not -BeNullOrEmpty 30 | } 31 | 32 | It 'Has a valid description' { 33 | $manifestData.Description | Should -Not -BeNullOrEmpty 34 | } 35 | 36 | It 'Has a valid author' { 37 | $manifestData.Author | Should -Not -BeNullOrEmpty 38 | } 39 | 40 | It 'Has a valid guid' { 41 | {[guid]::Parse($manifestData.Guid)} | Should -Not -Throw 42 | } 43 | 44 | It 'Has a valid copyright' { 45 | $manifestData.CopyRight | Should -Not -BeNullOrEmpty 46 | } 47 | } 48 | } 49 | 50 | Describe 'Git tagging' -Skip { 51 | BeforeAll { 52 | $gitTagVersion = $null 53 | 54 | # Ensure to only pull in a single git executable (in case multiple git's are found on path). 55 | if ($git = (Get-Command git -CommandType Application -ErrorAction SilentlyContinue)[0]) { 56 | $thisCommit = & $git log --decorate --oneline HEAD~1..HEAD 57 | if ($thisCommit -match $gitTagMatchRegEx) { $gitTagVersion = $matches[1] } 58 | } 59 | } 60 | 61 | It 'Is tagged with a valid version' { 62 | $gitTagVersion | Should -Not -BeNullOrEmpty 63 | $gitTagVersion -as [Version] | Should -Not -BeNullOrEmpty 64 | } 65 | 66 | It 'Matches manifest version' { 67 | $manifestData.Version -as [Version] | Should -Be ( $gitTagVersion -as [Version]) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/Meta.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | 3 | Set-StrictMode -Version latest 4 | 5 | # Make sure MetaFixers.psm1 is loaded - it contains Get-TextFilesList 6 | Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'MetaFixers.psm1') -Verbose:$false -Force 7 | 8 | $projectRoot = $ENV:BHProjectPath 9 | if (-not $projectRoot) { 10 | $projectRoot = $PSScriptRoot 11 | } 12 | 13 | $allTextFiles = Get-TextFilesList $projectRoot 14 | $unicodeFilesCount = 0 15 | $totalTabsCount = 0 16 | foreach ($textFile in $allTextFiles) { 17 | if (Test-FileUnicode $textFile) { 18 | $unicodeFilesCount++ 19 | Write-Warning ( 20 | "File $($textFile.FullName) contains 0x00 bytes." + 21 | " It probably uses Unicode/UTF-16 and needs to be converted to UTF-8." + 22 | " Use Fixer 'Get-UnicodeFilesList `$pwd | ConvertTo-UTF8'." 23 | ) 24 | } 25 | $unicodeFilesCount | Should -Be 0 26 | 27 | $fileName = $textFile.FullName 28 | (Get-Content $fileName -Raw) | Select-String "`t" | Foreach-Object { 29 | Write-Warning ( 30 | "There are tabs in $fileName." + 31 | " Use Fixer 'Get-TextFilesList `$pwd | ConvertTo-SpaceIndentation'." 32 | ) 33 | $totalTabsCount++ 34 | } 35 | } 36 | } 37 | 38 | Describe 'Text files formatting' { 39 | Context 'File encoding' { 40 | It "No text file uses Unicode/UTF-16 encoding" { 41 | $unicodeFilesCount | Should -Be 0 42 | } 43 | } 44 | 45 | Context 'Indentations' { 46 | It "No text file use tabs for indentations" { 47 | $totalTabsCount | Should -Be 0 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/MetaFixers.psm1: -------------------------------------------------------------------------------- 1 | # Taken with love from https://github.com/PowerShell/DscResource.Tests/blob/master/MetaFixers.psm1 2 | 3 | <# 4 | This module helps fix problems, found by Meta.Tests.ps1 5 | #> 6 | 7 | $ErrorActionPreference = 'stop' 8 | Set-StrictMode -Version latest 9 | 10 | function ConvertTo-UTF8() { 11 | [CmdletBinding()] 12 | [OutputType([void])] 13 | param( 14 | [Parameter(Mandatory, ValueFromPipeline)] 15 | [System.IO.FileInfo]$FileInfo 16 | ) 17 | 18 | process { 19 | $content = Get-Content -Raw -Encoding Unicode -Path $FileInfo.FullName 20 | [System.IO.File]::WriteAllText($FileInfo.FullName, $content, [System.Text.Encoding]::UTF8) 21 | } 22 | } 23 | 24 | function ConvertTo-SpaceIndentation() { 25 | [CmdletBinding()] 26 | [OutputType([void])] 27 | param( 28 | [Parameter(Mandatory, ValueFromPipeline)] 29 | [IO.FileInfo]$FileInfo 30 | ) 31 | 32 | process { 33 | $content = (Get-Content -Raw -Path $FileInfo.FullName) -replace "`t", ' ' 34 | [IO.File]::WriteAllText($FileInfo.FullName, $content) 35 | } 36 | } 37 | 38 | function Get-TextFilesList { 39 | [CmdletBinding()] 40 | [OutputType([IO.FileInfo])] 41 | param( 42 | [Parameter(Mandatory, ValueFromPipeline)] 43 | [string]$Root 44 | ) 45 | 46 | begin { 47 | $txtFileExtentions = @('.gitignore', '.gitattributes', '.ps1', '.psm1', '.psd1', '.json', '.xml', '.cmd', '.mof') 48 | } 49 | 50 | process { 51 | Get-ChildItem -Path $Root -File -Recurse | 52 | Where-Object { $_.Extension -in $txtFileExtentions } 53 | } 54 | } 55 | 56 | function Test-FileUnicode { 57 | [CmdletBinding()] 58 | [OutputType([bool])] 59 | param( 60 | [Parameter(Mandatory, ValueFromPipeline)] 61 | [IO.FileInfo]$FileInfo 62 | ) 63 | 64 | process { 65 | $bytes = [IO.File]::ReadAllBytes($FileInfo.FullName) 66 | $zeroBytes = @($bytes -eq 0) 67 | return [bool]$zeroBytes.Length 68 | } 69 | } 70 | 71 | function Get-UnicodeFilesList() { 72 | [CmdletBinding()] 73 | [OutputType([IO.FileInfo])] 74 | param( 75 | [Parameter(Mandatory)] 76 | [string]$Root 77 | ) 78 | 79 | $root | Get-TextFilesList | Where-Object { Test-FileUnicode $_ } 80 | } 81 | -------------------------------------------------------------------------------- /tests/ScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | } 4 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", 3 | "version": "0.1", 4 | "publicReleaseRefSpec": [ 5 | "^refs/heads/main$", 6 | "^refs/heads/v\\d+(?:(\\.\\d+){2})?$" 7 | ], 8 | "cloudBuild": { 9 | "buildNumber": { 10 | "enabled": true 11 | }, 12 | "setVersionVariables": true 13 | }, 14 | "release": { 15 | "tagName": "v{version}", 16 | "branchName": "v{version}", 17 | "versionIncrement": "minor", 18 | "firstUnstableTag": "alpha" 19 | } 20 | } 21 | --------------------------------------------------------------------------------