Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save metablaster/52b1baac5be44e2f1e6d16800813f42f to your computer and use it in GitHub Desktop.
Save metablaster/52b1baac5be44e2f1e6d16800813f42f to your computer and use it in GitHub Desktop.

Revisions

  1. metablaster revised this gist Apr 21, 2024. 1 changed file with 141 additions and 98 deletions.
    Original file line number Diff line number Diff line change
    @@ -14,66 +14,73 @@

    **NOTE:** This tutorial is partially out of date.

    The following stuff mentioned in this tutorial is no longer neccessary:
    The following stuff mentioned in this tutorial is no longer necessary:

    1. **Step 2, 3, 9 and 10** chocolately and custom OpenSSH is not a requirement, OpenSSH that comes with Windows will work, only make sure to set it auto start and create an ECDSA key.
    1. **Step 2, 3, 9 and 10** chocolately and custom `OpenSSH` is not a requirement,
    `OpenSSH` that comes with Windows will work, only make sure to set it auto start and create an ECDSA key.

    2. **Step 16** to create an `ECDSA` key run:

    ```powershell
    # if .ssh directory doesn't exist create it
    mkdir $env:USERPROFILE\.ssh
    ```powershell
    # if .ssh directory doesn't exist create it
    mkdir $env:USERPROFILE\.ssh
    # Create new ECDSA key
    ssh-keygen -t ecdsa -b 521 -C "GitHub" -f $env:USERPROFILE\.ssh\key_file_name
    ```
    # Create new ECDSA key
    ssh-keygen -t ecdsa -b 521 -C "GitHub" -f $env:USERPROFILE\.ssh\key_file_name
    ```
    3. **Step 18** is not recommended because it's may cause issues with `gpg-agent` reading created file, you can configure all this in `Kleopatra` UI as well.
    3. **Step 18** is not recommended because it's may cause issues with `gpg-agent` reading created file,
    you can configure all this in `Kleopatra` UI as well.
    4. **Step 19** Installing pre-release of `posh-git` is no longer neccessary since there is a release version now, just omit the `-AllowPrerelase` switch.
    4. **Step 19** Installing pre-release of `posh-git` is no longer necessary since there is a release version now,
    just omit the `-AllowPrerelease` switch.
    The rest of the tutorial should work fine for years to come, but I'm leaving outdated material intact to serve for research and troubleshooting.
    The rest of the tutorial should work fine for years to come,
    but I'm leaving outdated material intact to serve for research and troubleshooting.
    ## This tutorial will grant you following benefits
    >- work with git in Powershell, you won't need to use MSYS terminal any more
    >- you will have colored prompt in powershell when in working tree
    >- git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    >- your commits will be automatically signed by default
    >- git will use gpg-agent from gpg4win suite, to sign your commits (meaning being able to manage and generate your keys with Kleopatra as well as many other GUI options for GPG)
    >- git will use gpg-agent from gpg4win suite, to sign your commits (meaning being able to manage and generate your keys
    with Kleopatra as well as many other GUI options for GPG)
    >- you will be asked for gpg key only once, with the ability to customize how often gpg asks you for GPG key password
    >- you will communicate with github over ssh
    ## Summary of the problem
    git comes as you might know bundled with it's own gpg and ssh executables, however if you want git to use gpg4win version of gpg
    for signing commits and if you don't want to be prompted for ssh and gpg keys every time you push and commit and if in addition
    you want all that in powershell then you are likely to get into a lot of trouble.
    git comes as you might know bundled with it's own gpg and ssh executables, however if you want git to
    use gpg4win version of gpg for signing commits and if you don't want to be prompted for ssh and gpg
    keys every time you push and commit and if in addition you want all that in powershell then you are
    likely to get into a lot of trouble.
    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you just want to be able to cache keys in a more efficient ways.
    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you
    just want to be able to cache keys in a more efficient ways.
    the biggest problem is that ssh that comes with git doesn't run ssh-agent automatically, posh-git doesn't start
    The biggest problem is that ssh that comes with git doesn't run ssh-agent automatically, posh-git doesn't start
    ssh-agent properly at the time of writing, (maybe some new version in the future will), because there is a conflict between
    openSSH that comes with windows and ssh that comes with git, so the alternative way is to use OpenSSH that comes bundled
    openSSH that comes with windows and ssh that comes with git, so the alternative way is to use `OpenSSH` that comes bundled
    with Windows 10.
    For more information see [OpenSSH in Windows](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview)
    However even that won't work perfectly because bundled ssh in Windows 10 is out of date and outputs annoying
    signature warning when doing push (at least on Windows 1903), so we need to install manually latest version of OpenSSH!
    signature warning when doing push (at least on Windows 1903), so we need to install manually latest version of `OpenSSH`!
    note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal because ssh that comes with git
    doesn't offer windows service!
    Note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal
    because ssh that comes with git doesn't offer windows service!
    I won't go into details too much as to providing technical details why default setup doesn't work,
    because it would take a lot of explanation, and since you're reading this you might already know that!
    ## Tutorial steps
    **NOTE:** Portion of the steps here are based on instructions from documentation on `github.com` but updated to reflect powershell usage,
    and some stuff has been removed because it's irrelevant with our setup.
    **NOTE:** Portion of the steps here are based on instructions from documentation on `github.com` but
    updated to reflect powershell usage, and some stuff has been removed because it's irrelevant with our setup.
    Also some of the content is based on `git-scm.com` instructions and many other sites, the point is that all this information is now assembled
    here in one place for a complete tutorial.
    Also some of the content is based on `git-scm.com` instructions and many other sites,
    the point is that all this information is now assembled here in one place for a complete tutorial.
    At the end of this tutorial is a list of links to original documentation and references that describe the problem.
    @@ -90,29 +97,32 @@ also these steps have been tested on Windows 10 only
    - select "Manage optional features" to go to the Setting App.
    - click on "OpenSSH Client" and uninstall
    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Package` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.
    3. There are multiple ways to install `chocolatey` as explained [here](https://chocolatey.org/docs/installation)
    we'll use `Install-Package` version and if that doesn't work then `nuget.exe` option because these
    seem to be the most practical options.
    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:
    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is
    pretty old so let's first check powershell version, Open up powershell and type:
    ```powershell
    $PSVersionTable.PSVersion
    ```
    In order for all of the commands in this tutorial to work you will need at least Windows PowerShell 5.x or PowerShell Core 6.0.
    If for some reason you can't upgrade powershell this tutorial provides a subset of alternative commands that will work
    except `posh-git` module which requires powershell minimum version 5.
    In order for all of the commands in this tutorial to work you will need at least Windows PowerShell 5.x
    or PowerShell Core 6.0.\
    If for some reason you can't upgrade powershell this tutorial provides a subset of alternative
    commands that will work except `posh-git` module which requires powershell minimum version 5.
    To grab and install latest PowerShell core follow this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)
    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation opportunities
    as explained on this link:
    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update,
    but with some restricted installation opportunities as explained on this link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)
    5. Before you're able to run PowerShell scripts on your machine, you need to set your local ExecutionPolicy to RemoteSigned
    More about [PowerShell Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6)
    More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6)
    - More about [PowerShell Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6)
    - More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6)
    6. Open up Powershell (Admin) and check current execution policy:
    @@ -122,15 +132,17 @@ so let's first check powershell version, Open up powershell and type:
    **NOTE:** PowerShell Core defaults to `RemoteSigned` while Windows PowerShell defaults to `Restricted`
    if it's not RemoteSigned change execution policy:
    If it's not `RemoteSigned` change execution policy:
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```
    7. Because we'll install some modules, you might want to set `NuGet` and `PSGallery` package sources as trusted, also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).
    7. Because we'll install some modules, you might want to set `NuGet` and `PSGallery` package sources as trusted,
    also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).
    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may
    fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.
    To see package sources first run:
    @@ -169,13 +181,17 @@ so let's first check powershell version, Open up powershell and type:
    Find-PackageProvider -Name "NuGet" -AllVersions
    ```
    If NuGet is out of date or not installed run new Powershell (Admin) instance and install it (or update with `-Force` switch),
    If NuGet is out of date or not installed run new Powershell (Admin) instance and install it
    (or update with `-Force` switch)
    ```powershell
    Install-PackageProvider -Name NuGet
    ```
    Restart administrative PowerShell and then we also need to update PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you should get an error:
    Restart administrative PowerShell and then we also need to update PowerShellGet version which is
    required for latest posh-git, this is possible to install only with `-Force` switch as explained
    [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7),
    otherwise you should get an error:
    To see currently installed versions:
    @@ -195,53 +211,63 @@ so let's first check powershell version, Open up powershell and type:
    Update-Module -Name PowerShellGet
    ```
    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 sets of commands before executing them,
    and make sure you use `-Force` with `Install-Module`
    If you get an error such as "Unable to find module providers" in Windows PowerShell
    (in core it might not work anyway) restart administrative powershell for each of these 2 sets of
    commands before executing them, and make sure you use `-Force` with `Install-Module`
    9. Next again restart admin powershell and search for available chocolatey versions:
    9. Next again restart admin powershell and search for available `chocolatey` versions:
    **NOTE:** command below may fail in PowerShell core, if so there is "option 2" for you.
    **NOTE:** Command below may fail in PowerShell core, if so there is "option 2" for you.
    ```powershell
    Find-Package chocolatey -MinimumVersion 0.10.14`
    ```
    Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I prefer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)\
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based on Microsoft fork on github, the difference is that this one will also give us the option to install windows service for ssh-agent.\
    Install `chocolatey` by using either option 1 or option 2:
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and `chocolatey` but
    I prefer the easy way.\
    If you wish to build it from source grab ported sources here:
    [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based
    on Microsoft fork on github, the difference is that this one will also give us the option to
    install windows service for ssh-agent.\
    To input more parameters see previous openssh link, we use `-pre` to get latest prerelease.
    **OPTION 1: Using Install-Package**
    To download chocolatey, replace `RequiredVersion` option\
    To download `chocolatey`, replace `RequiredVersion` option\
    with version obtained from `Find-Package` above:
    ```powershell
    Install-Package -Name chocolatey -ProviderName NuGet -RequiredVersion x.x.x
    ```
    Next to install chocolatey do:
    Next to install `chocolatey` do:
    `Initialize-Chocolatey`
    this should finish installation, if this does not work then:\
    **NOTE:** update `cd` command to match chocolatey version
    **NOTE:** update `cd` command to match `chocolatey` version
    ```powershell
    cd "C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.0.10.14\tools"
    & .\chocolateyInstall.ps1
    ```
    Finally to install OpenSSH, restart administrative PowerShell and run:\
    Finally to install `OpenSSH`, restart administrative PowerShell and run:\
    `choco install openssh -pre --package-parameters="/SSHAgentFeature"`
    **OPTION 2: Using nuget.exe**
    This is alternative method to install chocolatey and OpenSSH:
    This is alternative method to install `chocolatey` and `OpenSSH`:
    Get latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads), put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.
    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com).\
    **NOTE:** if you wish to install chocolately somewhere else update first command, and ensure chosen path is in `%PATH%` environment variable.
    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/),
    and we need `chocolatey` because it will let us install [openssh](https://www.openssh.com).
    **NOTE:** if you wish to install chocolately somewhere else update first command,
    and ensure chosen path is in `%PATH%` environment variable.
    ```powershell
    cd C:\tools
    @@ -251,25 +277,26 @@ so let's first check powershell version, Open up powershell and type:
    choco install openssh -pre --package-parameters="/SSHAgentFeature"
    ```
    10. For option 1, `Install-Package` will download chocolatey into:\
    `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\
    For option2: nuget.exe will temporary download chocolatey to `C:\tools\chocolatey.x.x.x`.
    10. For option 1, `Install-Package` will download `chocolatey` into:\
    `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\
    For option2: nuget.exe will temporary download `chocolatey` to `C:\tools\chocolatey.x.x.x`.
    In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and OpenSSH with service configuration will be installed into `C:\Program Files\OpenSSH-Win64`.
    In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and `OpenSSH` with
    service configuration will be installed into `C:\Program Files\OpenSSH-Win64`.
    11. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.
    11. Now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.
    12. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that ssh and gpg paths below are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:
    12. Close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that ssh and gpg paths below are correct paths on your system, and if not update as needed,
    for example, if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:
    ```powershell
    where.exe ssh
    where.exe gpg
    ```
    Now start telling git about our setup: (btw. hard to tell why this silly syntax for paths)
    Now start telling git about our setup: (btw. hard to tell why this syntax for paths)
    ```powershell
    git config --global --replace-all core.sshCommand "'C:\Program Files\OpenSSH-Win64\ssh.exe'"
    @@ -291,19 +318,21 @@ You can verify installation path by typing:
    program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe
    ```
    **NOTE:** above paths are pointing git to use gpg4win executables of gpg and our fresh installed openSSH portable as ssh program
    **NOTE:** above paths are pointing git to use gpg4win executables of gpg and our fresh installed
    openSSH portable as ssh program
    13. Now everything is set up, and it's time to setup the keys!
    If you have existing gpg keys made by gpg4win in `%appdata%\gnupg` which you would like to backup first (because we might override
    them) then issue the following command:
    If you have existing gpg keys made by gpg4win in `%appdata%\gnupg` which you would like to backup
    first (because we might override them) then issue the following command:
    ```powershell
    robocopy $env:APPDATA\gnupg $env:APPDATA\gnupg-backup /MOVE /E
    ```
    if you have existing gpg keys in `~\.gnupg` which is where gpg keys are put by git version of gpg and you would like to use
    them with gpg4win to sign commits, then issue following commands to move entry conents into `%appdata%\gnupg`
    If you have existing gpg keys in `~\.gnupg` which is where gpg keys are put by git version of
    gpg and you would like to use them with gpg4win to sign commits, then issue the following
    commands to move entire contents into `%appdata%\gnupg`
    ```powershell
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    @@ -312,7 +341,7 @@ You can verify installation path by typing:
    If you have existing key somewhere else (ex. backup on USB) then import them with Kleopatra.
    14. Otherwise if you don't have any gpg keys at all then generate new keys.
    you can generate gpg keys with Kleopatra that comes with gpg4win or you can do the same in powershell by typing:
    you can generate gpg keys with Kleopatra that comes with gpg4win or you can do the same in powershell by typing:
    ```powershell
    gpg --default-new-key-algo rsa4096 --gen-key
    @@ -326,9 +355,10 @@ you can generate gpg keys with Kleopatra that comes with gpg4win or you can do t
    gpg --list-secret-keys --keyid-format LONG
    ```
    From the list of GPG keys, copy the GPG key ID you'd like to use. In the following example, the GPG key ID is `3AA5C34371567BD2`
    From the list of GPG keys, copy the GPG key ID you'd like to use. In the following example,
    the GPG key ID is `3AA5C34371567BD2`
    example:
    Example:
    ```powershell
    C:\Users\User> gpg --list-secret-keys --keyid-format LONG
    @@ -365,12 +395,14 @@ you can generate gpg keys with Kleopatra that comes with gpg4win or you can do t
    del gpgkey.txt
    ```
    Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key** and pres **CTRL+V** into box to paste the key.
    Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key** and press
    **CTRL+V** into box to paste the key.
    16. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    are (will be) stored because all ssh programs write keys to same directory that is `~\.ssh`
    16. Same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to
    worry about where keys are (will be) stored because all ssh programs write keys to same directory
    that is `~\.ssh`
    type following to generate new keys:
    Type following to generate new keys:
    ```powershell
    ssh-keygen -t rsa -b 4096 -C "[email protected]"
    @@ -386,15 +418,16 @@ are (will be) stored because all ssh programs write keys to same directory that
    mkdir $env:USERPROFILE\.ssh
    ```
    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.ssh` folder.
    Copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.ssh` folder.
    Once you have your keys in default location, add your private key to ssh-agent:
    ```powershell
    ssh-add $env:USERPROFILE\.ssh\id_rsa
    ```
    **NOTE:** `ssh-add` without arguments adds the default keys `~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa. ~/ssh/id_ed25519, and ~/.ssh/identity` if they exist.
    **NOTE:** `ssh-add` without arguments adds the default keys
    `~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa. ~/ssh/id_ed25519, and ~/.ssh/identity` if they exist.
    Copy ssh public key to clipboard (again if `Set-Clipboard` doesn't work see second command below)
    @@ -412,17 +445,19 @@ are (will be) stored because all ssh programs write keys to same directory that
    del sshkey.txt
    ```
    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.
    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and press
    **CTRL+V** into box to paste the key.
    17. You also want to tell git about yourself, for users of private email type in private email below ex. `[email protected]`:
    17. You also want to tell git about yourself, for users of private email type in private email below ex.
    `[email protected]`:
    ```powershell
    git config --global user.name "your name or username"
    git config --global user.email [email protected]
    ```
    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 2h so that you don't have to input
    gpg key password every time you commit!
    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 2h so that
    you don't have to input gpg key password every time you commit!
    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:
    @@ -452,33 +487,36 @@ gpg key password every time you commit!
    gpgconf --launch gpg-agent
    ```
    you can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    You can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    Above numbers mean, default-cache 2h, max-cache 4h and pin entry 2 minutes.
    The meaning of these options is as follows:
    - default-cache-ttl n
    Sets the time a cache entry is valid to n seconds. Each time a cache entry is accessed, the entry's timer is reset.
    Default is 10 minutes (600 seconds)
    - max-cache-ttl n
    Sets the maximum time a cache entry is valid to n seconds. After this time a cache entry will be expired even if it has been accessed recently.
    Sets the maximum time a cache entry is valid to n seconds. After this time a cache entry
    will be expired even if it has been accessed recently.
    Default is 2 hours (7200 seconds)
    - pinentry-timeout n
    This option sets the pinentry to timeout after n seconds with no user input.
    Default value of 0 does not ask the pinentry to timeout
    19. now last thing to do is to install posh-git module so that you get color prompt in powershell when working with git repos.
    19. Now last thing to do is to install posh-git module so that you get color prompt in powershell when working with git repos.
    More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options
    **NOTE:** If you have at least PowerShell 5 with PackageManagement installed, you can use the package manager to install posh-git for you.
    **NOTE:** If you have at least PowerShell 5 with PackageManagement installed,
    you can use the package manager to install posh-git for you.
    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:
    Close Administrative powershell and the other powershell too, to update environment and open a
    new user mode powershell, then install posh-git:
    First we need to check and if necessary set execution policy for current user,
    Open up Powershell (standard user) and check current execution policy:
    @@ -487,7 +525,7 @@ gpg key password every time you commit!
    Get-ExecutionPolicy
    ```
    if it's not RemoteSigned change execution policy:
    If it's not RemoteSigned change execution policy:
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    @@ -512,8 +550,8 @@ gpg key password every time you commit!
    Add-PoshGitToProfile -AllHosts
    ```
    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`
    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and
    a separate one for the ISE. That's why we use `-AllHosts`
    20. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell, default its `Restricted` and for PowerShell Core it is `RemoteSigned`
    @@ -524,10 +562,15 @@ gpg key password every time you commit!
    ## Final step and your opinion
    That's it, it's recommended to reboot system and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, and the ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password either
    every 2h or max. 4h
    That's it, it's recommended to reboot system and start testing your git setup with PowerShell,
    try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell,
    and the ssh-agent will not ask you for password because it runs as service on Windows,
    and also gpg-agent will ask you for password either every 2h or max. 4h
    **NOTE:** Now treat your MSYS terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the MSYS terminal itself continues to use old settings and variables and ssh-agent will most likely not cache your keys because in MSYS terminal environment there are now two ssh programs resulting in conflict.
    **NOTE:** Now treat your MSYS terminal that comes with git as obsolete on your system,
    you have no reason to use it anymore, because even though git will use your new setup the MSYS terminal
    itself continues to use old settings and variables and ssh-agent will most likely not cache your keys
    because in MSYS terminal environment there are now two ssh programs resulting in conflict.
    If you encounter problems or have suggestion please report.
    happy coding! :grinning:
    @@ -567,8 +610,8 @@ happy coding! :grinning:
    `gpg-agent --gpgconf-test`
    - If things don't work well wit gpg even after reboot, make sure to **delete** `gpg-agent.conf` file, and set these settings in Kleopatra
    program that comes with gpg4win in following location
    - If things don't work well wit gpg even after reboot, make sure to **delete** `gpg-agent.conf` file,
    and set these settings in Kleopatra program that comes with gpg4win in following location
    - Kleopatra -> Settings -> Configure Kleopatra -> GnuPG system -> Private keys -> Options controlling the security
    - Here setup caching options, click apply/OK to let Kleopatra generate new gpg-agent.conf and reboot system
  2. metablaster revised this gist Dec 22, 2022. 1 changed file with 3 additions and 3 deletions.
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@

    The following stuff mentioned in this tutorial is no longer neccessary:

    1. **Step 9 and 10** chocolately and custom OpenSSH is not a requirement, OpenSSH that comes with Windows will work, only make sure to set it auto start and create an ECDSA key.
    1. **Step 2, 3, 9 and 10** chocolately and custom OpenSSH is not a requirement, OpenSSH that comes with Windows will work, only make sure to set it auto start and create an ECDSA key.

    2. **Step 16** to create an `ECDSA` key run:

    @@ -228,7 +228,7 @@ so let's first check powershell version, Open up powershell and type:
    ```powershell
    cd "C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.0.10.14\tools"
    `& .\chocolateyInstall.ps1
    & .\chocolateyInstall.ps1
    ```
    Finally to install OpenSSH, restart administrative PowerShell and run:\
    @@ -527,7 +527,7 @@ gpg key password every time you commit!
    That's it, it's recommended to reboot system and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, and the ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password either
    every 2h or max. 4h
    **NOTE:** Now Treat your MSYS terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the MSYS terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside MSYS terminal environment there are two ssh programs resulting in conflict.
    **NOTE:** Now treat your MSYS terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the MSYS terminal itself continues to use old settings and variables and ssh-agent will most likely not cache your keys because in MSYS terminal environment there are now two ssh programs resulting in conflict.
    If you encounter problems or have suggestion please report.
    happy coding! :grinning:
  3. metablaster revised this gist Dec 13, 2022. 1 changed file with 1 addition and 1 deletion.
    Original file line number Diff line number Diff line change
    @@ -32,7 +32,7 @@ ssh-keygen -t ecdsa -b 521 -C "GitHub" -f $env:USERPROFILE\.ssh\key_file_name

    4. **Step 19** Installing pre-release of `posh-git` is no longer neccessary since there is a release version now, just omit the `-AllowPrerelase` switch.

    The rest of the tutorial should work fine for years to come.
    The rest of the tutorial should work fine for years to come, but I'm leaving outdated material intact to serve for research and troubleshooting.

    ## This tutorial will grant you following benefits

  4. metablaster revised this gist Dec 13, 2022. 1 changed file with 1 addition and 1 deletion.
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    # Table of contents

    - [Table of contents](#table-of-contents)
    - [Update 2 years later](#update-3-years-later)
    - [Update 2 years later](#update-2-years-later)
    - [This tutorial will grant you following benefits](#this-tutorial-will-grant-you-following-benefits)
    - [Summary of the problem](#summary-of-the-problem)
    - [Tutorial steps](#tutorial-steps)
  5. metablaster revised this gist Dec 13, 2022. 1 changed file with 2 additions and 2 deletions.
    Original file line number Diff line number Diff line change
    @@ -2,15 +2,15 @@
    # Table of contents

    - [Table of contents](#table-of-contents)
    - [Update 3 years later](#update-3-years-later)
    - [Update 2 years later](#update-3-years-later)
    - [This tutorial will grant you following benefits](#this-tutorial-will-grant-you-following-benefits)
    - [Summary of the problem](#summary-of-the-problem)
    - [Tutorial steps](#tutorial-steps)
    - [Final step and your opinion](#final-step-and-your-opinion)
    - [Troubleshooting GPG key caching](#troubleshooting-gpg-key-caching)
    - [References](#references)

    ## Update 3 years later
    ## Update 2 years later

    **NOTE:** This tutorial is partially out of date.

  6. metablaster revised this gist Dec 13, 2022. 1 changed file with 1 addition and 0 deletions.
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    # Table of contents

    - [Table of contents](#table-of-contents)
    - [Update 3 years later](#update-3-years-later)
    - [This tutorial will grant you following benefits](#this-tutorial-will-grant-you-following-benefits)
    - [Summary of the problem](#summary-of-the-problem)
    - [Tutorial steps](#tutorial-steps)
  7. metablaster revised this gist Dec 13, 2022. 1 changed file with 24 additions and 0 deletions.
    Original file line number Diff line number Diff line change
    @@ -9,6 +9,30 @@
    - [Troubleshooting GPG key caching](#troubleshooting-gpg-key-caching)
    - [References](#references)

    ## Update 3 years later

    **NOTE:** This tutorial is partially out of date.

    The following stuff mentioned in this tutorial is no longer neccessary:

    1. **Step 9 and 10** chocolately and custom OpenSSH is not a requirement, OpenSSH that comes with Windows will work, only make sure to set it auto start and create an ECDSA key.

    2. **Step 16** to create an `ECDSA` key run:

    ```powershell
    # if .ssh directory doesn't exist create it
    mkdir $env:USERPROFILE\.ssh
    # Create new ECDSA key
    ssh-keygen -t ecdsa -b 521 -C "GitHub" -f $env:USERPROFILE\.ssh\key_file_name
    ```

    3. **Step 18** is not recommended because it's may cause issues with `gpg-agent` reading created file, you can configure all this in `Kleopatra` UI as well.

    4. **Step 19** Installing pre-release of `posh-git` is no longer neccessary since there is a release version now, just omit the `-AllowPrerelase` switch.

    The rest of the tutorial should work fine for years to come.

    ## This tutorial will grant you following benefits

    >- work with git in Powershell, you won't need to use MSYS terminal any more
  8. metablaster revised this gist Nov 9, 2020. 1 changed file with 7 additions and 7 deletions.
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@

    ## This tutorial will grant you following benefits

    >- work with git in Powershell, you won't need to use msys terminal any more
    >- work with git in Powershell, you won't need to use MSYS terminal any more
    >- you will have colored prompt in powershell when in working tree
    >- git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    >- your commits will be automatically signed by default
    @@ -175,7 +175,7 @@ so let's first check powershell version, Open up powershell and type:
    9. Next again restart admin powershell and search for available chocolatey versions:
    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.
    **NOTE:** command below may fail in PowerShell core, if so there is "option 2" for you.
    ```powershell
    Find-Package chocolatey -MinimumVersion 0.10.14`
    @@ -210,7 +210,7 @@ so let's first check powershell version, Open up powershell and type:
    `choco install openssh -pre --package-parameters="/SSHAgentFeature"`
    **OPTION 2: Using nuget.exe**
    This is alternative method to install chocolatey and OpenSHH:
    This is alternative method to install chocolatey and OpenSSH:
    Get latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads), put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.
    @@ -235,7 +235,7 @@ For option2: nuget.exe will temporary download chocolatey to `C:\tools\chocolate
    11. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.
    12. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    Please first ensure that ssh and gpg paths below are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:
    @@ -361,7 +361,7 @@ are (will be) stored because all ssh programs write keys to same directory that
    mkdir $env:USERPROFILE\.ssh
    ```
    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.shh` folder.
    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.ssh` folder.
    Once you have your keys in default location, add your private key to ssh-agent:
    @@ -389,7 +389,7 @@ are (will be) stored because all ssh programs write keys to same directory that
    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.
    17. You also want to tell git about yourself:
    17. You also want to tell git about yourself, for users of private email type in private email below ex. `[email protected]`:
    ```powershell
    git config --global user.name "your name or username"
    @@ -502,7 +502,7 @@ gpg key password every time you commit!
    That's it, it's recommended to reboot system and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, and the ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password either
    every 2h or max. 4h
    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environment there are two ssh programs resulting in conflict.
    **NOTE:** Now Treat your MSYS terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the MSYS terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside MSYS terminal environment there are two ssh programs resulting in conflict.
    If you encounter problems or have suggestion please report.
    happy coding! :grinning:
  9. metablaster revised this gist Aug 24, 2020. 1 changed file with 11 additions and 7 deletions.
    Original file line number Diff line number Diff line change
    @@ -15,8 +15,8 @@
    >- you will have colored prompt in powershell when in working tree
    >- git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    >- your commits will be automatically signed by default
    >- git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    >- you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    >- git will use gpg-agent from gpg4win suite, to sign your commits (meaning being able to manage and generate your keys with Kleopatra as well as many other GUI options for GPG)
    >- you will be asked for gpg key only once, with the ability to customize how often gpg asks you for GPG key password
    >- you will communicate with github over ssh
    ## Summary of the problem
    @@ -499,7 +499,7 @@ gpg key password every time you commit!
    ## Final step and your opinion
    That's it, reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, and the ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password either
    That's it, it's recommended to reboot system and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, and the ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password either
    every 2h or max. 4h
    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environment there are two ssh programs resulting in conflict.
    @@ -512,21 +512,25 @@ happy coding! :grinning:
    - Show options used by gpg-agent now
    `gpgconf --list-options gpg-agent`
    In this output you want to see values your options only and make sure values are those you entered into gpg-agent.conf
    - See if gpg-agent has issues with options
    `gpgconf --check-options gpg-agent`
    result of `gpg-agent.exe:1:1:` means no problems, anything else is error
    - List directories used by gpg suite
    `gpgconf --list-dirs`
    what you are looking for here is `homedir` which is where your gpg-agent.conf must be saved to be recognized
    - Test gpg-agent.conf file
    - Test gpg-agent.conf file (replace USERNAME with your )
    `gpgconf --check-config "$env:appdata\\gnupg\\gpg-agent.conf"`
    `gpgconf --check-config "C:\\Users\\USERNAME\\AppData\\Roaming\\gnupg\\gpg-agent.conf"`
    Test gpg-agent.conf file, this will likely fail probably a bug
    - Test gpg software suite
    @@ -538,11 +542,11 @@ happy coding! :grinning:
    `gpg-agent --gpgconf-test`
    - If things don't work well wit gpg, make sure to delete gpg-agent.conf file and set these settings in Kleopatra
    - If things don't work well wit gpg even after reboot, make sure to **delete** `gpg-agent.conf` file, and set these settings in Kleopatra
    program that comes with gpg4win in following location
    - Kleopatra -> Settings -> Configure Kleopatra -> GnuPG system -> Private keys -> Options controlling the security
    - Here setup cache options, click apply/OK to let Kleopatra generate gpg-agent.conf and reboot system
    - Here setup caching options, click apply/OK to let Kleopatra generate new gpg-agent.conf and reboot system
    ## References
  10. metablaster revised this gist Aug 24, 2020. 1 changed file with 28 additions and 22 deletions.
    Original file line number Diff line number Diff line change
    @@ -402,22 +402,22 @@ gpg key password every time you commit!
    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:
    ```powershell
    New-Item -Path $(Write-Output $env:appdata\gnupg\gpg-agent.conf) -ItemType "file"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "default-cache-ttl 7200"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "max-cache-ttl 10800"
    New-Item -Path $env:appdata\gnupg\gpg-agent.conf -ItemType File
    Set-Content -Path $env:appdata\gnupg\gpg-agent.conf -Encoding utf8 -Value "default-cache-ttl 7200"
    Add-Content -Path $env:appdata\gnupg\gpg-agent.conf -Encoding utf8 -Value "max-cache-ttl 14400"
    ```
    To set pin entry to wait max. 1 minute for input set:
    To set pin entry to wait 2 minutes for input set:
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    Add-Content -Path $env:appdata\gnupg\gpg-agent.conf -Encoding utf8 -Value "pinentry-timeout 120"
    ```
    To have gpg-agent log it's activity about password caching (debug number 6), substitute "your_username" in the command below with your actual user name.
    To have gpg-agent log it's activity about password caching run this:
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "log-file C:\Users\<your_username>\AppData\Roaming\gnupg\gpg-agent.log"
    Add-Content -Path $env:appdata\gnupg\gpg-agent.conf -Encoding utf8 -Value "debug-level guru"
    Add-Content -Path $env:appdata\gnupg\gpg-agent.conf -Encoding utf8 -Value "log-file $env:appdata\gnupg\gpg-agent.log"
    ```
    Next we stop gpg-agent and start it again:
    @@ -428,22 +428,24 @@ gpg key password every time you commit!
    ```
    you can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    Above numbers mean, default-cache 2h, max-cache 3h and pin entry 1min.
    Above numbers mean, default-cache 2h, max-cache 4h and pin entry 2 minutes.
    The meaning of these settings is as follows:
    The meaning of these options is as follows:
    - default-cache-ttl n
    Set the time a cache entry is valid to n seconds. The default is 600 seconds. Each time a cache entry is accessed, the entry's timer is reset.
    Sets the time a cache entry is valid to n seconds. Each time a cache entry is accessed, the entry's timer is reset.
    Default is 10 minutes (600 seconds)
    - max-cache-ttl n
    Set the maximum time a cache entry is valid to n seconds. After this time a cache entry will be expired even if it has been accessed recently, default is 2 hours (7200 seconds)
    Sets the maximum time a cache entry is valid to n seconds. After this time a cache entry will be expired even if it has been accessed recently.
    Default is 2 hours (7200 seconds)
    - pinentry-timeout n
    This option sets the pinentry to timeout after n seconds with no user input.
    The default value of 0 does not ask the pinentry to timeout
    Default value of 0 does not ask the pinentry to timeout
    19. now last thing to do is to install posh-git module so that you get color prompt in powershell when working with git repos.
    @@ -497,7 +499,8 @@ gpg key password every time you commit!
    ## Final step and your opinion
    That's it, reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, where ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password only once per terminal session!
    That's it, reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, and the ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password either
    every 2h or max. 4h
    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environment there are two ssh programs resulting in conflict.
    @@ -509,34 +512,37 @@ happy coding! :grinning:
    - Show options used by gpg-agent now
    `gpgconf --list-options gpg-agent`
    In this output you want to see values your options only and make sure values are those you entered into gpg-agent.conf
    - Check the options for the gpg-agent component
    - See if gpg-agent has issues with options
    `gpgconf --check-options gpg-agent`
    result of `gpg-agent.exe:1:1:` means no problems, anything else is error
    - List directories used by gpg software suite
    - List directories used by gpg suite
    `gpgconf --list-dirs`
    what you are looking for here is `homedir` which is where your gpg-agent.conf must be saved to be recognized
    - Test gpg-agent.conf file
    `gpgconf --check-config "C:\\Users\\USERNAME\\AppData\\Roaming\\gnupg\\gpg-agent.conf"`
    Test gpg-agent.conf file, this will likely fail probably a bug
    - Test gpg software suite
    `gpgconf --check-programs`
    - Show options in gpg-agent.conf file used by gpg-agent
    `gpg-agent --gpgconf-list`
    Verify all programs of gpg suite are OK (status must be :1:1)
    - parse the configuration file and returns with failure if the configuration file would prevent gpg from startup
    `gpg-agent --gpgconf-test`
    - More gpg-agent options
    - If things don't work well wit gpg, make sure to delete gpg-agent.conf file and set these settings in Kleopatra
    program that comes with gpg4win in following location
    `gpg-agent --help`
    - Kleopatra -> Settings -> Configure Kleopatra -> GnuPG system -> Private keys -> Options controlling the security
    - Here setup cache options, click apply/OK to let Kleopatra generate gpg-agent.conf and reboot system
    ## References
  11. metablaster renamed this gist Aug 24, 2020. 1 changed file with 0 additions and 0 deletions.
  12. metablaster revised this gist Aug 24, 2020. 1 changed file with 0 additions and 500 deletions.
    Original file line number Diff line number Diff line change
    @@ -1,500 +0,0 @@

    After struggling for hours and hours it's time to share information on how to setup ultimate git combination for windows!

    ## FOLLOWING THIS TUTORIAL WILL GRANT YOU FOLLOWING BENEFITS

    >- work with git in Powershell, you won't need to use msys terminal any more
    >- you will have colored prompt in powershell when in working tree
    >- git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    >- your commits will be automatically signed by default
    >- git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    >- you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    >- you will communicate with github over ssh
    ## SUMMARY OF THE PROBLEM

    git comes as you might know bundled with it's own gpg and ssh executables, however if you want git to use gpg4win version of gpg
    for signing commits and if you don't want to be prompted for ssh and gpg keys every time you push and commit and if in addition
    you want all that in powershell then you are likely to get into a lot of trouble.

    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you just want to be able to cache keys in a more efficient ways.

    the biggest problem is that ssh that comes with git doesn't run ssh-agent automatically, posh-git doesn't start
    ssh-agent properly at the time of writing, (maybe some new version in the future will), because there is a conflict between
    openSSH that comes with windows and ssh that comes with git, so the alternative way is to use OpenSSH that comes bundled
    with Windows 10.
    For more information see [OpenSSH in Windows](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview)

    However even that won't work perfectly because bundled ssh in Windows 10 is out of date and outputs annoying
    signature warning when doing push (at least on Windows 1903), so we need to install manually latest version of OpenSSH!

    note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal because ssh that comes with git
    doesn't offer windows service!

    I won't go into details too much as to providing technical details why default setup doesn't work,
    because it would take a lot of explanation, and since you're reading this you might already know that!

    ## TUTORIAL STEPS

    **NOTE:** Portion of the steps here are based on instructions from documentation on `github.com` but updated to reflect powershell usage,
    and some stuff has been removed because it's irrelevant with our setup.

    Also some of the content is based on `git-scm.com` instructions and many other sites, the point is that all this information is now assembled
    here in one place for a complete tutorial.

    At the end of this tutorial is a list of links to original documentation and references that describe the problem.

    **NOTE:** All of the commands below are executed in powershell,
    also these steps have been tested on Windows 10 only

    1. First if you didn't already download and install [gpg4win](https://www.gpg4win.org/download.html) and [git](https://git-scm.com/)
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows:

    - log into Administrative account (if you're not Administrator)
    - press `Windows key + I` to open settings
    - type "Optional Feature" from the list
    - select "Manage optional features" to go to the Setting App.
    - click on "OpenSSH Client" and uninstall

    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Package` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.

    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:

    ```powershell
    $PSVersionTable.PSVersion
    ```

    In order for all of the commands in this tutorial to work you will need at least Windows PowerShell 5.x or PowerShell Core 6.0.
    If for some reason you can't upgrade powershell this tutorial provides a subset of alternative commands that will work
    except `posh-git` module which requires powershell minimum version 5.

    To grab and install latest PowerShell core follow this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)

    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation opportunities
    as explained on this link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)

    5. Before you're able to run PowerShell scripts on your machine, you need to set your local ExecutionPolicy to RemoteSigned
    More about [PowerShell Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6)
    More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6)

    6. Open up Powershell (Admin) and check current execution policy:

    ```powershell
    Get-ExecutionPolicy
    ```

    **NOTE:** PowerShell Core defaults to `RemoteSigned` while Windows PowerShell defaults to `Restricted`

    if it's not RemoteSigned change execution policy:

    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    7. Because we'll install some modules, you might want to set `NuGet` and `PSGallery` package sources as trusted, also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).

    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.

    To see package sources first run:

    ```powershell
    Get-PackageSource
    ```

    To set nuget.org as trusted run:

    ```powershell
    Set-PackageSource -Name nuget.org -Trusted
    ```

    More information about [NuGet provider](https://docs.microsoft.com/en-us/nuget/what-is-nuget)

    To set PSGallery as trusted run:

    ```powershell
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
    ```

    More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/powershell/gallery/overview)

    8. Next logical step is to install/update prerequisites.

    Let's first check if we have required NuGet package provider installed:

    ```powershell
    Get-PackageProvider
    ```

    If NuGet is not listed (or to check if it's out of date) find out if it's possible to install/update it:

    ```powershell
    Find-PackageProvider -Name "NuGet" -AllVersions
    ```

    If NuGet is out of date or not installed run new Powershell (Admin) instance and install it (or update with `-Force` switch),

    ```powershell
    Install-PackageProvider -Name NuGet
    ```

    Restart administrative PowerShell and then we also need to update PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you should get an error:

    To see currently installed versions:

    ```powershell
    Get-Module -ListAvailable -Name PowerShellGet
    ```

    To install new version on top of that is preinstalled:

    ```powershell
    Install-Module -Name PowerShellGet -Force
    ```

    To update existing PowerShellGet: (the one you personally already installed with `Install-Module`)

    ```powershell
    Update-Module -Name PowerShellGet
    ```

    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 sets of commands before executing them,
    and make sure you use `-Force` with `Install-Module`

    9. Next again restart admin powershell and search for available chocolatey versions:

    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.

    ```powershell
    Find-Package chocolatey -MinimumVersion 0.10.14`
    ```

    Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I prefer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)\
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based on Microsoft fork on github, the difference is that this one will also give us the option to install windows service for ssh-agent.\
    To input more parameters see previous openssh link, we use `-pre` to get latest prerelease.

    **OPTION 1: Using Install-Package**
    To download chocolatey, replace `RequiredVersion` option\
    with version obtained from `Find-Package` above:

    ```powershell
    Install-Package -Name chocolatey -ProviderName NuGet -RequiredVersion x.x.x
    ```

    Next to install chocolatey do:
    `Initialize-Chocolatey`

    this should finish installation, if this does not work then:\
    **NOTE:** update `cd` command to match chocolatey version

    ```powershell
    cd "C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.0.10.14\tools"
    `& .\chocolateyInstall.ps1
    ```

    Finally to install OpenSSH, restart administrative PowerShell and run:\
    `choco install openssh -pre --package-parameters="/SSHAgentFeature"`

    **OPTION 2: Using nuget.exe**
    This is alternative method to install chocolatey and OpenSHH:

    Get latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads), put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.

    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com).\
    **NOTE:** if you wish to install chocolately somewhere else update first command, and ensure chosen path is in `%PATH%` environment variable.

    ```powershell
    cd C:\tools
    nuget install chocolatey
    cd choco*\tools
    & .\chocolateyInstall.ps1
    choco install openssh -pre --package-parameters="/SSHAgentFeature"
    ```

    10. For option 1, `Install-Package` will download chocolatey into:\
    `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\
    For option2: nuget.exe will temporary download chocolatey to `C:\tools\chocolatey.x.x.x`.

    In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and OpenSSH with service configuration will be installed into `C:\Program Files\OpenSSH-Win64`.

    11. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.

    12. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:

    ```powershell
    where.exe ssh
    where.exe gpg
    ```

    Now start telling git about our setup: (btw. hard to tell why this silly syntax for paths)

    ```powershell
    git config --global --replace-all core.sshCommand "'C:\Program Files\OpenSSH-Win64\ssh.exe'"
    git config --global --replace-all gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    ```

    And to verify these commands are input correctly:

    ```powershell
    git config --global --edit
    ```

    The input must look like this (I'm showing this so that tutorial changes don't mess up with expected result):

    ```
    [core]
    sshCommand = 'C:\\Program Files\\OpenSSH-Win64\\ssh.exe'
    [gpg]
    program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe
    ```

    **NOTE:** above paths are pointing git to use gpg4win executables of gpg and our fresh installed openSSH portable as ssh program

    13. Now everything is set up, and it's time to setup the keys!

    If you have existing gpg keys made by gpg4win in `%appdata%\gnupg` which you would like to backup first (because we might override
    them) then issue the following command:

    ```powershell
    robocopy $env:APPDATA\gnupg $env:APPDATA\gnupg-backup /MOVE /E
    ```

    if you have existing gpg keys in `~\.gnupg` which is where gpg keys are put by git version of gpg and you would like to use
    them with gpg4win to sign commits, then issue following commands to move entry conents into `%appdata%\gnupg`

    ```powershell
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    ```

    If you have existing key somewhere else (ex. backup on USB) then import them with Kleopatra.

    14. Otherwise if you don't have any gpg keys at all then generate new keys.
    you can generate gpg keys with Kleopatra that comes with gpg4win or you can do the same in powershell by typing:

    ```powershell
    gpg --default-new-key-algo rsa4096 --gen-key
    ```

    At the prompt, specify your options, email, password etc. when asked.

    15. Now it's time to gather information and tell git about our gpg keys:

    ```powershell
    gpg --list-secret-keys --keyid-format LONG
    ```

    From the list of GPG keys, copy the GPG key ID you'd like to use. In the following example, the GPG key ID is `3AA5C34371567BD2`

    example:

    ```powershell
    C:\Users\User> gpg --list-secret-keys --keyid-format LONG
    C:/Users/User/AppData/Roaming/gnupg/pubring.kbx
    -----------------------------------------------
    sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
    4096R/42B317FD4BA89E7A
    uid [ultimate] your_username (key for github) <[email protected]>
    ssb 4096R/42B317FD4BA89E7A 2017-09-13 [E] [expires: 2017-09-12]
    ```

    Paste the text below, substituting in the GPG key ID you'd like to use.
    Tell git about your signing key, and tell it that you want to sign all commits by default:

    ```powershell
    git config --global user.signingkey 3AA5C34371567BD2
    git config --global commit.gpgsign true
    ```

    Export public key to clipboard (Note that Set-Clipboard cmdlet works only with newer powershell versions)
    if Set-Clipboard doesn't work export the the key using cmd, as shown in the second command:

    ```powershell
    gpg --armor --export 3AA5C34371567BD2 | Set-Clipboard
    ```

    Version to export public key to clipboard if `Set-Clipboard` doesn't work:

    ```powershell
    gpg --armor --export 3AA5C34371567BD2 > gpgkey.txt
    cmd
    clip < gpgkey.txt
    exit
    del gpgkey.txt
    ```

    Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key** and pres **CTRL+V** into box to paste the key.

    16. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    are (will be) stored because all ssh programs write keys to same directory that is `~\.ssh`

    type following to generate new keys:

    ```powershell
    ssh-keygen -t rsa -b 4096 -C "[email protected]"
    ```

    When you're prompted to "Enter a file in which to save the key," press Enter.
    This accepts the default file location, also specify new password for the key.

    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:\
    **NOTE:** I provide command for this because on server platforms it might not be possible with mouse.

    ```powershell
    mkdir $env:USERPROFILE\.ssh
    ```

    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.shh` folder.

    Once you have your keys in default location, add your private key to ssh-agent:

    ```powershell
    ssh-add $env:USERPROFILE\.ssh\id_rsa
    ```

    **NOTE:** `ssh-add` without arguments adds the default keys `~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa. ~/ssh/id_ed25519, and ~/.ssh/identity` if they exist.

    Copy ssh public key to clipboard (again if `Set-Clipboard` doesn't work see second command below)

    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub | Set-Clipboard
    ```

    Version to copy ssh public key to clipboard if `Set-Clipboard` doesn't work:

    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub > sshkey.txt
    cmd
    clip < sshkey.txt
    exit
    del sshkey.txt
    ```

    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.

    17. You also want to tell git about yourself:

    ```powershell
    git config --global user.name "your name or username"
    git config --global user.email [email protected]
    ```

    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 2h so that you don't have to input
    gpg key password every time you commit!

    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:

    ```powershell
    New-Item -Path $(Write-Output $env:appdata\gnupg\gpg-agent.conf) -ItemType "file"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "default-cache-ttl 7200"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "max-cache-ttl 10800"
    ```

    To set pin entry to wait max. 1 minute for input set:

    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    ```

    To have gpg-agent log it's activity about password caching (debug number 6), substitute "your_username" in the command below with your actual user name.

    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "log-file C:\Users\<your_username>\AppData\Roaming\gnupg\gpg-agent.log"
    ```

    Next we stop gpg-agent and start it again:

    ```powershell
    gpgconf --kill gpg-agent
    gpgconf --launch gpg-agent
    ```

    you can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    Above numbers mean, default-cache 2h, max-cache 3h and pin entry 1min.

    19. now last thing to do is to install posh-git module so that you get nice color prompt in powershell when working with git
    repos.
    More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options

    **NOTE:** If you have at least PowerShell 5 with PackageManagement installed, you can use the package manager to install posh-git for you.

    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:

    First we need to check and if necessary set execution policy for current user,
    Open up Powershell (standard user) and check current execution policy:

    ```powershell
    Get-ExecutionPolicy
    ```

    if it's not RemoteSigned change execution policy:

    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    If you never installed posh-git then:

    ```powershell
    PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease
    ```

    Otherwise to update existing one:

    ```powershell
    PowerShellGet\Update-Module posh-git
    ```

    Finally import module and tell powershell to import it each next time:

    ```powershell
    Import-Module posh-git
    Add-PoshGitToProfile -AllHosts
    ```

    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`

    20. Next if you want you can set compression level for git, this may prevent issues when cloning huge repositories
    of when pushing large commints, it also (if I'm not wrong) helps to reduce repository size.

    ```powershell
    git config --global --replace-all core.compression 9
    ```

    21. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell, default its `Restricted` and for PowerShell Core it is `RemoteSigned`

    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    ## FINAL STEP AND YOUR OPINION

    That's it, reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, where ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password only once per terminal session!

    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environment there are two ssh programs resulting in conflict.

    If you encounter problems or have suggestion please report.
    happy coding! :grinning:

    ## REFERENCES

    This were the most useful links to help me out assemble this tutorial:

    - [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
    - [A-Git-in-Other-Environments-Git-in-PowerShell](https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-PowerShell)
    - [Windows 10 version 1803 broke my git SSH](https://adamralph.com/2018/05/15/windows-10-version-1803-broke-my-git-ssh/)
    - [GPG Agent Configuration](https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html)
    - [gpgconf - Modify .gnupg home directories](https://manpages.debian.org/testing/gpgconf/gpgconf.1.en.html)
    - [Moving from Windows 1809's OpenSSH to OpenSSH Portable](https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to-openssh-portable)

    ~metablaster
  13. metablaster revised this gist Aug 24, 2020. No changes.
  14. metablaster renamed this gist Aug 24, 2020. 1 changed file with 0 additions and 0 deletions.
  15. metablaster revised this gist Aug 24, 2020. 1 changed file with 557 additions and 0 deletions.
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,557 @@

    # Table of contents

    - [Table of contents](#table-of-contents)
    - [This tutorial will grant you following benefits](#this-tutorial-will-grant-you-following-benefits)
    - [Summary of the problem](#summary-of-the-problem)
    - [Tutorial steps](#tutorial-steps)
    - [Final step and your opinion](#final-step-and-your-opinion)
    - [Troubleshooting GPG key caching](#troubleshooting-gpg-key-caching)
    - [References](#references)

    ## This tutorial will grant you following benefits

    >- work with git in Powershell, you won't need to use msys terminal any more
    >- you will have colored prompt in powershell when in working tree
    >- git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    >- your commits will be automatically signed by default
    >- git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    >- you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    >- you will communicate with github over ssh
    ## Summary of the problem

    git comes as you might know bundled with it's own gpg and ssh executables, however if you want git to use gpg4win version of gpg
    for signing commits and if you don't want to be prompted for ssh and gpg keys every time you push and commit and if in addition
    you want all that in powershell then you are likely to get into a lot of trouble.

    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you just want to be able to cache keys in a more efficient ways.

    the biggest problem is that ssh that comes with git doesn't run ssh-agent automatically, posh-git doesn't start
    ssh-agent properly at the time of writing, (maybe some new version in the future will), because there is a conflict between
    openSSH that comes with windows and ssh that comes with git, so the alternative way is to use OpenSSH that comes bundled
    with Windows 10.
    For more information see [OpenSSH in Windows](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview)

    However even that won't work perfectly because bundled ssh in Windows 10 is out of date and outputs annoying
    signature warning when doing push (at least on Windows 1903), so we need to install manually latest version of OpenSSH!

    note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal because ssh that comes with git
    doesn't offer windows service!

    I won't go into details too much as to providing technical details why default setup doesn't work,
    because it would take a lot of explanation, and since you're reading this you might already know that!

    ## Tutorial steps

    **NOTE:** Portion of the steps here are based on instructions from documentation on `github.com` but updated to reflect powershell usage,
    and some stuff has been removed because it's irrelevant with our setup.

    Also some of the content is based on `git-scm.com` instructions and many other sites, the point is that all this information is now assembled
    here in one place for a complete tutorial.

    At the end of this tutorial is a list of links to original documentation and references that describe the problem.

    **NOTE:** All of the commands below are executed in powershell,
    also these steps have been tested on Windows 10 only

    1. First if you didn't already download and install [gpg4win](https://www.gpg4win.org/download.html) and [git](https://git-scm.com/)

    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows:

    - log into Administrative account (if you're not Administrator)
    - press `Windows key + I` to open settings
    - type "Optional Feature" from the list
    - select "Manage optional features" to go to the Setting App.
    - click on "OpenSSH Client" and uninstall

    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Package` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.

    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:

    ```powershell
    $PSVersionTable.PSVersion
    ```

    In order for all of the commands in this tutorial to work you will need at least Windows PowerShell 5.x or PowerShell Core 6.0.
    If for some reason you can't upgrade powershell this tutorial provides a subset of alternative commands that will work
    except `posh-git` module which requires powershell minimum version 5.

    To grab and install latest PowerShell core follow this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)

    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation opportunities
    as explained on this link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)

    5. Before you're able to run PowerShell scripts on your machine, you need to set your local ExecutionPolicy to RemoteSigned

    More about [PowerShell Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6)
    More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6)

    6. Open up Powershell (Admin) and check current execution policy:

    ```powershell
    Get-ExecutionPolicy
    ```
    **NOTE:** PowerShell Core defaults to `RemoteSigned` while Windows PowerShell defaults to `Restricted`
    if it's not RemoteSigned change execution policy:
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```
    7. Because we'll install some modules, you might want to set `NuGet` and `PSGallery` package sources as trusted, also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).
    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.
    To see package sources first run:
    ```powershell
    Get-PackageSource
    ```
    To set nuget.org as trusted run:
    ```powershell
    Set-PackageSource -Name nuget.org -Trusted
    ```
    More information about [NuGet provider](https://docs.microsoft.com/en-us/nuget/what-is-nuget)
    To set PSGallery as trusted run:
    ```powershell
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
    ```
    More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/powershell/gallery/overview)
    8. Next logical step is to install/update prerequisites.
    Let's first check if we have required NuGet package provider installed:
    ```powershell
    Get-PackageProvider
    ```
    If NuGet is not listed (or to check if it's out of date) find out if it's possible to install/update it:
    ```powershell
    Find-PackageProvider -Name "NuGet" -AllVersions
    ```
    If NuGet is out of date or not installed run new Powershell (Admin) instance and install it (or update with `-Force` switch),
    ```powershell
    Install-PackageProvider -Name NuGet
    ```
    Restart administrative PowerShell and then we also need to update PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you should get an error:
    To see currently installed versions:
    ```powershell
    Get-Module -ListAvailable -Name PowerShellGet
    ```
    To install new version on top of that is preinstalled:
    ```powershell
    Install-Module -Name PowerShellGet -Force
    ```
    To update existing PowerShellGet: (the one you personally already installed with `Install-Module`)
    ```powershell
    Update-Module -Name PowerShellGet
    ```
    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 sets of commands before executing them,
    and make sure you use `-Force` with `Install-Module`
    9. Next again restart admin powershell and search for available chocolatey versions:
    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.
    ```powershell
    Find-Package chocolatey -MinimumVersion 0.10.14`
    ```
    Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I prefer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)\
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based on Microsoft fork on github, the difference is that this one will also give us the option to install windows service for ssh-agent.\
    To input more parameters see previous openssh link, we use `-pre` to get latest prerelease.
    **OPTION 1: Using Install-Package**
    To download chocolatey, replace `RequiredVersion` option\
    with version obtained from `Find-Package` above:
    ```powershell
    Install-Package -Name chocolatey -ProviderName NuGet -RequiredVersion x.x.x
    ```
    Next to install chocolatey do:
    `Initialize-Chocolatey`
    this should finish installation, if this does not work then:\
    **NOTE:** update `cd` command to match chocolatey version
    ```powershell
    cd "C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.0.10.14\tools"
    `& .\chocolateyInstall.ps1
    ```
    Finally to install OpenSSH, restart administrative PowerShell and run:\
    `choco install openssh -pre --package-parameters="/SSHAgentFeature"`
    **OPTION 2: Using nuget.exe**
    This is alternative method to install chocolatey and OpenSHH:
    Get latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads), put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.
    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com).\
    **NOTE:** if you wish to install chocolately somewhere else update first command, and ensure chosen path is in `%PATH%` environment variable.
    ```powershell
    cd C:\tools
    nuget install chocolatey
    cd choco*\tools
    & .\chocolateyInstall.ps1
    choco install openssh -pre --package-parameters="/SSHAgentFeature"
    ```
    10. For option 1, `Install-Package` will download chocolatey into:\
    `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\
    For option2: nuget.exe will temporary download chocolatey to `C:\tools\chocolatey.x.x.x`.
    In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and OpenSSH with service configuration will be installed into `C:\Program Files\OpenSSH-Win64`.
    11. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.
    12. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:
    ```powershell
    where.exe ssh
    where.exe gpg
    ```
    Now start telling git about our setup: (btw. hard to tell why this silly syntax for paths)
    ```powershell
    git config --global --replace-all core.sshCommand "'C:\Program Files\OpenSSH-Win64\ssh.exe'"
    git config --global --replace-all gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    ```
    And to verify these commands are input correctly:
    ```powershell
    git config --global --edit
    ```
    The input must look like this (I'm showing this so that tutorial changes don't mess up with expected result):
    ```none
    [core]
    sshCommand = 'C:\\Program Files\\OpenSSH-Win64\\ssh.exe'
    [gpg]
    program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe
    ```
    **NOTE:** above paths are pointing git to use gpg4win executables of gpg and our fresh installed openSSH portable as ssh program
    13. Now everything is set up, and it's time to setup the keys!
    If you have existing gpg keys made by gpg4win in `%appdata%\gnupg` which you would like to backup first (because we might override
    them) then issue the following command:
    ```powershell
    robocopy $env:APPDATA\gnupg $env:APPDATA\gnupg-backup /MOVE /E
    ```
    if you have existing gpg keys in `~\.gnupg` which is where gpg keys are put by git version of gpg and you would like to use
    them with gpg4win to sign commits, then issue following commands to move entry conents into `%appdata%\gnupg`
    ```powershell
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    ```
    If you have existing key somewhere else (ex. backup on USB) then import them with Kleopatra.
    14. Otherwise if you don't have any gpg keys at all then generate new keys.
    you can generate gpg keys with Kleopatra that comes with gpg4win or you can do the same in powershell by typing:
    ```powershell
    gpg --default-new-key-algo rsa4096 --gen-key
    ```
    At the prompt, specify your options, email, password etc. when asked.
    15. Now it's time to gather information and tell git about our gpg keys:
    ```powershell
    gpg --list-secret-keys --keyid-format LONG
    ```
    From the list of GPG keys, copy the GPG key ID you'd like to use. In the following example, the GPG key ID is `3AA5C34371567BD2`
    example:
    ```powershell
    C:\Users\User> gpg --list-secret-keys --keyid-format LONG
    C:/Users/User/AppData/Roaming/gnupg/pubring.kbx
    -----------------------------------------------
    sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
    4096R/42B317FD4BA89E7A
    uid [ultimate] your_username (key for github) <[email protected]>
    ssb 4096R/42B317FD4BA89E7A 2017-09-13 [E] [expires: 2017-09-12]
    ```
    Paste the text below, substituting in the GPG key ID you'd like to use.
    Tell git about your signing key, and tell it that you want to sign all commits by default:
    ```powershell
    git config --global user.signingkey 3AA5C34371567BD2
    git config --global commit.gpgsign true
    ```
    Export public key to clipboard (Note that Set-Clipboard cmdlet works only with newer powershell versions)
    if Set-Clipboard doesn't work export the the key using cmd, as shown in the second command:
    ```powershell
    gpg --armor --export 3AA5C34371567BD2 | Set-Clipboard
    ```
    Version to export public key to clipboard if `Set-Clipboard` doesn't work:
    ```powershell
    gpg --armor --export 3AA5C34371567BD2 > gpgkey.txt
    cmd
    clip < gpgkey.txt
    exit
    del gpgkey.txt
    ```
    Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key** and pres **CTRL+V** into box to paste the key.
    16. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    are (will be) stored because all ssh programs write keys to same directory that is `~\.ssh`
    type following to generate new keys:
    ```powershell
    ssh-keygen -t rsa -b 4096 -C "[email protected]"
    ```
    When you're prompted to "Enter a file in which to save the key," press Enter.
    This accepts the default file location, also specify new password for the key.
    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:\
    **NOTE:** I provide command for this because on server platforms it might not be possible with mouse.
    ```powershell
    mkdir $env:USERPROFILE\.ssh
    ```
    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.shh` folder.
    Once you have your keys in default location, add your private key to ssh-agent:
    ```powershell
    ssh-add $env:USERPROFILE\.ssh\id_rsa
    ```
    **NOTE:** `ssh-add` without arguments adds the default keys `~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa. ~/ssh/id_ed25519, and ~/.ssh/identity` if they exist.
    Copy ssh public key to clipboard (again if `Set-Clipboard` doesn't work see second command below)
    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub | Set-Clipboard
    ```
    Version to copy ssh public key to clipboard if `Set-Clipboard` doesn't work:
    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub > sshkey.txt
    cmd
    clip < sshkey.txt
    exit
    del sshkey.txt
    ```
    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.
    17. You also want to tell git about yourself:
    ```powershell
    git config --global user.name "your name or username"
    git config --global user.email [email protected]
    ```
    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 2h so that you don't have to input
    gpg key password every time you commit!
    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:
    ```powershell
    New-Item -Path $(Write-Output $env:appdata\gnupg\gpg-agent.conf) -ItemType "file"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "default-cache-ttl 7200"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "max-cache-ttl 10800"
    ```
    To set pin entry to wait max. 1 minute for input set:
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    ```
    To have gpg-agent log it's activity about password caching (debug number 6), substitute "your_username" in the command below with your actual user name.
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "log-file C:\Users\<your_username>\AppData\Roaming\gnupg\gpg-agent.log"
    ```
    Next we stop gpg-agent and start it again:
    ```powershell
    gpgconf --kill gpg-agent
    gpgconf --launch gpg-agent
    ```
    you can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    Above numbers mean, default-cache 2h, max-cache 3h and pin entry 1min.
    The meaning of these settings is as follows:
    - default-cache-ttl n
    Set the time a cache entry is valid to n seconds. The default is 600 seconds. Each time a cache entry is accessed, the entry's timer is reset.
    - max-cache-ttl n
    Set the maximum time a cache entry is valid to n seconds. After this time a cache entry will be expired even if it has been accessed recently, default is 2 hours (7200 seconds)
    - pinentry-timeout n
    This option sets the pinentry to timeout after n seconds with no user input.
    The default value of 0 does not ask the pinentry to timeout
    19. now last thing to do is to install posh-git module so that you get color prompt in powershell when working with git repos.
    More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options
    **NOTE:** If you have at least PowerShell 5 with PackageManagement installed, you can use the package manager to install posh-git for you.
    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:
    First we need to check and if necessary set execution policy for current user,
    Open up Powershell (standard user) and check current execution policy:
    ```powershell
    Get-ExecutionPolicy
    ```
    if it's not RemoteSigned change execution policy:
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```
    If you never installed posh-git then:
    ```powershell
    PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease
    ```
    Otherwise to update existing one:
    ```powershell
    PowerShellGet\Update-Module posh-git
    ```
    Finally import module and tell powershell to import it each next time:
    ```powershell
    Import-Module posh-git
    Add-PoshGitToProfile -AllHosts
    ```
    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`
    20. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell, default its `Restricted` and for PowerShell Core it is `RemoteSigned`
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```
    ## Final step and your opinion
    That's it, reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, where ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password only once per terminal session!
    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environment there are two ssh programs resulting in conflict.
    If you encounter problems or have suggestion please report.
    happy coding! :grinning:
    ## Troubleshooting GPG key caching
    - Show options used by gpg-agent now
    `gpgconf --list-options gpg-agent`
    - Check the options for the gpg-agent component
    `gpgconf --check-options gpg-agent`
    - List directories used by gpg software suite
    `gpgconf --list-dirs`
    - Test gpg-agent.conf file
    `gpgconf --check-config "C:\\Users\\USERNAME\\AppData\\Roaming\\gnupg\\gpg-agent.conf"`
    - Test gpg software suite
    `gpgconf --check-programs`
    - Show options in gpg-agent.conf file used by gpg-agent
    `gpg-agent --gpgconf-list`
    - parse the configuration file and returns with failure if the configuration file would prevent gpg from startup
    `gpg-agent --gpgconf-test`
    - More gpg-agent options
    `gpg-agent --help`
    ## References
    This were the most useful links to help me out assemble this tutorial:
    - [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
    - [Git in PowerShell](https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-PowerShell)
    - [Windows 10 version 1803 broke my git SSH](https://adamralph.com/2018/05/15/windows-10-version-1803-broke-my-git-ssh/)
    - [Moving from Windows 1809's OpenSSH to OpenSSH Portable](https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to-openssh-portable)
    - [GPG Agent Configuration](https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html)
    - [Invoking gpgconf](https://www.gnupg.org/documentation/manuals/gnupg/Invoking-gpgconf.html)
    - [GPG Esoteric Options](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Esoteric-Options.html)
  16. metablaster revised this gist Aug 24, 2020. No changes.
  17. metablaster renamed this gist Aug 20, 2020. 1 changed file with 0 additions and 0 deletions.
  18. metablaster revised this gist Aug 20, 2020. 1 changed file with 8 additions and 1 deletion.
    Original file line number Diff line number Diff line change
    @@ -463,7 +463,14 @@ Add-PoshGitToProfile -AllHosts
    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`

    20. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    20. Next if you want you can set compression level for git, this may prevent issues when cloning huge repositories
    of when pushing large commints, it also (if I'm not wrong) helps to reduce repository size.

    ```powershell
    git config --global --replace-all core.compression 9
    ```

    21. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell, default its `Restricted` and for PowerShell Core it is `RemoteSigned`

    ```powershell
  19. metablaster revised this gist Aug 11, 2020. 1 changed file with 7 additions and 7 deletions.
    Original file line number Diff line number Diff line change
    @@ -3,13 +3,13 @@ After struggling for hours and hours it's time to share information on how to se

    ## FOLLOWING THIS TUTORIAL WILL GRANT YOU FOLLOWING BENEFITS

    - work with git in Powershell, you won't need to use msys terminal any more
    - you will have colored prompt in powershell when in working tree
    - git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    - your commits will be automatically signed by default
    - git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    - you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    - you will communicate with github over ssh
    >- work with git in Powershell, you won't need to use msys terminal any more
    >- you will have colored prompt in powershell when in working tree
    >- git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    >- your commits will be automatically signed by default
    >- git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    >- you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    >- you will communicate with github over ssh
    ## SUMMARY OF THE PROBLEM

  20. metablaster revised this gist Aug 11, 2020. 1 changed file with 13 additions and 18 deletions.
    Original file line number Diff line number Diff line change
    @@ -3,13 +3,13 @@ After struggling for hours and hours it's time to share information on how to se

    ## FOLLOWING THIS TUTORIAL WILL GRANT YOU FOLLOWING BENEFITS

    > 1. work with git in Powershell, you won't need to use msys terminal any more
    > 2. you will have colored prompt in powershell when in working tree
    > 3. git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    > 4. your commits will be automatically signed by default
    > 5. git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    > 6. you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    > 7. you will communicate with github over ssh
    - work with git in Powershell, you won't need to use msys terminal any more
    - you will have colored prompt in powershell when in working tree
    - git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    - your commits will be automatically signed by default
    - git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    - you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    - you will communicate with github over ssh

    ## SUMMARY OF THE PROBLEM

    @@ -483,16 +483,11 @@ happy coding! :grinning:

    This were the most useful links to help me out assemble this tutorial:

    [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)

    [A-Git-in-Other-Environments-Git-in-PowerShell](https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-PowerShell)

    [Windows 10 version 1803 broke my git SSH](https://adamralph.com/2018/05/15/windows-10-version-1803-broke-my-git-ssh/)

    [GPG Agent Configuration](https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html)

    [gpgconf - Modify .gnupg home directories](https://manpages.debian.org/testing/gpgconf/gpgconf.1.en.html)

    [Moving from Windows 1809's OpenSSH to OpenSSH Portable](https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to-openssh-portable)
    - [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
    - [A-Git-in-Other-Environments-Git-in-PowerShell](https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-PowerShell)
    - [Windows 10 version 1803 broke my git SSH](https://adamralph.com/2018/05/15/windows-10-version-1803-broke-my-git-ssh/)
    - [GPG Agent Configuration](https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html)
    - [gpgconf - Modify .gnupg home directories](https://manpages.debian.org/testing/gpgconf/gpgconf.1.en.html)
    - [Moving from Windows 1809's OpenSSH to OpenSSH Portable](https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to-openssh-portable)

    ~metablaster
  21. metablaster revised this gist Aug 11, 2020. 1 changed file with 5 additions and 0 deletions.
    Original file line number Diff line number Diff line change
    @@ -484,10 +484,15 @@ happy coding! :grinning:
    This were the most useful links to help me out assemble this tutorial:

    [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)

    [A-Git-in-Other-Environments-Git-in-PowerShell](https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-PowerShell)

    [Windows 10 version 1803 broke my git SSH](https://adamralph.com/2018/05/15/windows-10-version-1803-broke-my-git-ssh/)

    [GPG Agent Configuration](https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html)

    [gpgconf - Modify .gnupg home directories](https://manpages.debian.org/testing/gpgconf/gpgconf.1.en.html)

    [Moving from Windows 1809's OpenSSH to OpenSSH Portable](https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to-openssh-portable)

    ~metablaster
  22. metablaster revised this gist Aug 11, 2020. 1 changed file with 20 additions and 4 deletions.
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@

    After struggling for hours and hours it's time to share information on how to setup ultimate git combination for windows!

    ## FOLLOWING THIS TUTORIAL WILL GRANT YOU FOLLOWING BENEFITS

    > 1. work with git in Powershell, you won't need to use msys terminal any more
    @@ -34,18 +36,21 @@ because it would take a lot of explanation, and since you're reading this you mi

    ## TUTORIAL STEPS

    **NOTE:** Portion of the steps here are copied from github.com tutorial but updated to reflect powershell usage, and some
    stuff has been removed because it's irrelevant with our setup.
    **NOTE:** Portion of the steps here are based on instructions from documentation on `github.com` but updated to reflect powershell usage,
    and some stuff has been removed because it's irrelevant with our setup.

    Also some of the content is copied from git-scm.com and other sites, the point is that all this information is now assembled
    Also some of the content is based on `git-scm.com` instructions and many other sites, the point is that all this information is now assembled
    here in one place for a complete tutorial.

    At the end of this tutorial is a list of links to original documentation and references that describe the problem.

    **NOTE:** All of the commands below are executed in powershell,
    also these steps have been tested on Windows 10 only

    1. First if you didn't already download and install [gpg4win](https://www.gpg4win.org/download.html) and [git](https://git-scm.com/)
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows, log into Administrative account then
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows:

    - log into Administrative account (if you're not Administrator)
    - press `Windows key + I` to open settings
    - type "Optional Feature" from the list
    - select "Manage optional features" to go to the Setting App.
    @@ -474,4 +479,15 @@ That's it, reboot system (if needed) and start testing your git setup with Power
    If you encounter problems or have suggestion please report.
    happy coding! :grinning:

    ## REFERENCES

    This were the most useful links to help me out assemble this tutorial:

    [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
    [A-Git-in-Other-Environments-Git-in-PowerShell](https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-PowerShell)
    [Windows 10 version 1803 broke my git SSH](https://adamralph.com/2018/05/15/windows-10-version-1803-broke-my-git-ssh/)
    [GPG Agent Configuration](https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html)
    [gpgconf - Modify .gnupg home directories](https://manpages.debian.org/testing/gpgconf/gpgconf.1.en.html)
    [Moving from Windows 1809's OpenSSH to OpenSSH Portable](https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to-openssh-portable)

    ~metablaster
  23. metablaster revised this gist Aug 11, 2020. 1 changed file with 55 additions and 45 deletions.
    Original file line number Diff line number Diff line change
    @@ -1,45 +1,43 @@
    After struggling for hours and hours it's time to share information on how to setup
    ultimate git combination for windows!

    ## FOLLOWING THIS TUTORIAL WILL GRANT YOU FOLLOWING BENEFITS:
    > 1. Work with git in Powershell, you won't need to use msys termial any more
    > 2. You will have colored prompt in powershell when in working tree
    > 3. Your commits will be automaticlly signed by default
    > 4. git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    > 5. you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    > 6. you will communicate with github over ssh
    > 7. git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    ## FOLLOWING THIS TUTORIAL WILL GRANT YOU FOLLOWING BENEFITS

    > 1. work with git in Powershell, you won't need to use msys terminal any more
    > 2. you will have colored prompt in powershell when in working tree
    > 3. git will not ask you for ssh password every time (not even after reboot) because ssh-agent will run as windows service.
    > 4. your commits will be automatically signed by default
    > 5. git will use gpg4win to sign your commits (meaning being able to manage and generate your keys with Kleopatra)
    > 6. you will be asked for gpg key only once, with the ability to customize how often gpg asks you for key password
    > 7. you will communicate with github over ssh
    ## SUMMARY OF THE PROBLEM:
    git comes as you migh know bundled with it's own gpg and ssh executables, however if you wan't git to use gpg4win version of gpg
    for signing commits and if you don't wan't to be prompted for ssh and gpg keys evry time you push and commit and if in addition
    you wan't all that in powershell then you are likely to get into a lot of troubles.
    ## SUMMARY OF THE PROBLEM

    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you just wan't to be able to cache keys in a more efficient ways.
    git comes as you might know bundled with it's own gpg and ssh executables, however if you want git to use gpg4win version of gpg
    for signing commits and if you don't want to be prompted for ssh and gpg keys every time you push and commit and if in addition
    you want all that in powershell then you are likely to get into a lot of trouble.

    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you just want to be able to cache keys in a more efficient ways.

    the biggest problem is that ssh that comes with git doesn't run ssh-agent automatically, posh-git doesn't start
    ssh-agent properly at the time of writing, (maybe some new version in the future will), because there is a conflict between
    openSSH that comes with windows and ssh that comes with git, so the alternative way is to use OpenSSH that comes bundled
    with Windows 10.
    with Windows 10.
    For more information see [OpenSSH in Windows](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview)

    However even that won't work perfectly because bundled ssh in Windows 10 is out of date and outputs anoying
    signature warning when doing push (at least on Windows 1903), so we need to install manually latest version of openssh!
    However even that won't work perfectly because bundled ssh in Windows 10 is out of date and outputs annoying
    signature warning when doing push (at least on Windows 1903), so we need to install manually latest version of OpenSSH!

    note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal because ssh that comes with git
    note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal because ssh that comes with git
    doesn't offer windows service!

    I won't go into details too much as to providing technicall details why default setup doesn't work,
    I won't go into details too much as to providing technical details why default setup doesn't work,
    because it would take a lot of explanation, and since you're reading this you might already know that!


    ## TUTORIAL STEPS:
    ## TUTORIAL STEPS

    **NOTE:** Portion of the steps here are copied from github.com tutorial but updated to reflect powershell usage, and some
    stuff has been removed because it's irrelevant with our setup.

    Also some of the conent is copied from git-scm.com and other sites, the point is that all this information is now assembled
    Also some of the content is copied from git-scm.com and other sites, the point is that all this information is now assembled
    here in one place for a complete tutorial.

    **NOTE:** All of the commands below are executed in powershell,
    @@ -53,7 +51,7 @@ also these steps have been tested on Windows 10 only
    - select "Manage optional features" to go to the Setting App.
    - click on "OpenSSH Client" and uninstall

    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Packge` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.
    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Package` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.

    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:
    @@ -63,12 +61,12 @@ $PSVersionTable.PSVersion
    ```

    In order for all of the commands in this tutorial to work you will need at least Windows PowerShell 5.x or PowerShell Core 6.0.
    If you for some reason can't upgrade powershell this tutorial provides subset of alternative commands that will work
    except posh-git which requires powershell version 5.
    If for some reason you can't upgrade powershell this tutorial provides a subset of alternative commands that will work
    except `posh-git` module which requires powershell minimum version 5.

    To grab and install latest PowerShell core follow this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)

    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation oportunities
    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation opportunities
    as explained on this link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)

    @@ -90,7 +88,7 @@ if it's not RemoteSigned change execution policy:
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    7. Because we'll install some modules, you might want to set NuGet and PSGalery package sources as trusted, also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).
    7. Because we'll install some modules, you might want to set `NuGet` and `PSGallery` package sources as trusted, also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).

    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.
    @@ -157,10 +155,10 @@ To update existing PowerShellGet: (the one you personally already installed with
    Update-Module -Name PowerShellGet
    ```

    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 sets of commands before exeuting them,
    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 sets of commands before executing them,
    and make sure you use `-Force` with `Install-Module`

    9. Next again restart admin powershell and search for availabe chocolatey versions:
    9. Next again restart admin powershell and search for available chocolatey versions:

    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.

    @@ -169,10 +167,10 @@ Find-Package chocolatey -MinimumVersion 0.10.14`
    ```

    Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I preffer the easy way.
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I prefer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)\
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based on Microsoft fork on github, the difference is that this one will also give us the option to install windows service for ssh-agent.\
    To input more parameters see previous openssh link, we use `-pre` to get latest prerelese.
    To input more parameters see previous openssh link, we use `-pre` to get latest prerelease.

    **OPTION 1: Using Install-Package**
    To download chocolatey, replace `RequiredVersion` option\
    @@ -187,12 +185,13 @@ Next to install chocolatey do:

    this should finish installation, if this does not work then:\
    **NOTE:** update `cd` command to match chocolatey version

    ```powershell
    cd "C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.0.10.14\tools"
    `& .\chocolateyInstall.ps1
    ```

    Finaly to install OpenSSH, restart administrative PowerShell and run:\
    Finally to install OpenSSH, restart administrative PowerShell and run:\
    `choco install openssh -pre --package-parameters="/SSHAgentFeature"`

    **OPTION 2: Using nuget.exe**
    @@ -202,7 +201,7 @@ Get latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads), put it som
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.

    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com).\
    **NOTE:** if you wish to install chocolately somewhere else update first command, and esure choosen path is in `%PATH%` evironment variable.
    **NOTE:** if you wish to install chocolately somewhere else update first command, and ensure chosen path is in `%PATH%` environment variable.

    ```powershell
    cd C:\tools
    @@ -224,20 +223,20 @@ In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:

    ```powershell
    where.exe ssh
    where.exe gpg
    ```

    Now start telling git about our setup: (btw. hard to tell why this silly sintax for paths)
    Now start telling git about our setup: (btw. hard to tell why this silly syntax for paths)

    ```powershell
    git config --global --replace-all core.sshCommand "'C:\Program Files\OpenSSH-Win64\ssh.exe'"
    git config --global --replace-all gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    ```

    And to verify these commands are input corectly:
    And to verify these commands are input correctly:

    ```powershell
    git config --global --edit
    @@ -252,17 +251,20 @@ The input must look like this (I'm showing this so that tutorial changes don't m
    program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe
    ```

    **NOTE:** above paths are pointing git to use gpg4win executalbe of gpg and our fresh installed openSSH portable as ssh program
    **NOTE:** above paths are pointing git to use gpg4win executables of gpg and our fresh installed openSSH portable as ssh program

    13. Now everything is set up, and it's time to setup the keys!

    If you have existing gpg keys made by gpg4win in `%appdata%\gnupg` which you would like to backup first (because we might override
    them) then issue the following command:

    ```powershell
    robocopy $env:APPDATA\gnupg $env:APPDATA\gnupg-backup /MOVE /E
    ```

    if you have existing gpg keys in `~\.gnupg` which is where gpg keys are put by git version of gpg and you would like to use
    them with gpg4win to sign commits, then issue following commands to move entry conents into `%appdata%\gnupg`

    ```powershell
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    ```
    @@ -275,16 +277,19 @@ you can generate gpg keys with Kleopatra that comes with gpg4win or you can do t
    ```powershell
    gpg --default-new-key-algo rsa4096 --gen-key
    ```

    At the prompt, specify your options, email, password etc. when asked.

    15. Now it's time to gather information and tell git about our gpg keys:

    ```powershell
    gpg --list-secret-keys --keyid-format LONG
    ```

    From the list of GPG keys, copy the GPG key ID you'd like to use. In the following example, the GPG key ID is `3AA5C34371567BD2`

    example:

    ```powershell
    C:\Users\User> gpg --list-secret-keys --keyid-format LONG
    C:/Users/User/AppData/Roaming/gnupg/pubring.kbx
    @@ -294,14 +299,16 @@ sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
    uid [ultimate] your_username (key for github) <[email protected]>
    ssb 4096R/42B317FD4BA89E7A 2017-09-13 [E] [expires: 2017-09-12]
    ```

    Paste the text below, substituting in the GPG key ID you'd like to use.
    Tell git about your signing key, and tell it that you want to sign all commits by default:

    ```powershell
    git config --global user.signingkey 3AA5C34371567BD2
    git config --global commit.gpgsign true
    ```
    Export public key to clipboard (Note taht Set-Clipboard cmdlet works only with newer powershell versions)

    Export public key to clipboard (Note that Set-Clipboard cmdlet works only with newer powershell versions)
    if Set-Clipboard doesn't work export the the key using cmd, as shown in the second command:

    ```powershell
    @@ -324,9 +331,11 @@ Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key*
    are (will be) stored because all ssh programs write keys to same directory that is `~\.ssh`

    type following to generate new keys:

    ```powershell
    ssh-keygen -t rsa -b 4096 -C "[email protected]"
    ```

    When you're prompted to "Enter a file in which to save the key," press Enter.
    This accepts the default file location, also specify new password for the key.

    @@ -353,7 +362,7 @@ Copy ssh public key to clipboard (again if `Set-Clipboard` doesn't work see seco
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub | Set-Clipboard
    ```

    Version to copy ssh public key to clipboard if `˙Set-Clipboard` doesn't work:
    Version to copy ssh public key to clipboard if `Set-Clipboard` doesn't work:

    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub > sshkey.txt
    @@ -389,7 +398,7 @@ To set pin entry to wait max. 1 minute for input set:
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    ```

    To have gpg-agent log it's activity about pasword caching (debug number 6), substitute "your_username" in the command below with your actual user name.
    To have gpg-agent log it's activity about password caching (debug number 6), substitute "your_username" in the command below with your actual user name.

    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    @@ -414,7 +423,7 @@ More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options

    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:

    First we need to check and if necesary set execution policy for current user,
    First we need to check and if necessary set execution policy for current user,
    Open up Powershell (standard user) and check current execution policy:

    ```powershell
    @@ -456,10 +465,11 @@ For Windows PowerShell, default its `Restricted` and for PowerShell Core it is `
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    ## FINAL STEP AND YOUR OPINION:
    That's it reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powersehll, where ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password only once per terminal session!
    ## FINAL STEP AND YOUR OPINION

    That's it, reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powershell, where ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password only once per terminal session!

    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even thouh git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environemnt there are two ssh programs resulting in conflict.
    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even though git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environment there are two ssh programs resulting in conflict.

    If you encounter problems or have suggestion please report.
    happy coding! :grinning:
  24. metablaster revised this gist Aug 11, 2020. 1 changed file with 49 additions and 13 deletions.
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,10 @@ also these steps have been tested on Windows 10 only
    1. First if you didn't already download and install [gpg4win](https://www.gpg4win.org/download.html) and [git](https://git-scm.com/)
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows, log into Administrative account then

    **Hit Start > Type "Optional Feature" > go to the Setting App. Check the "OpenSSH Client" and uninstall**
    - press `Windows key + I` to open settings
    - type "Optional Feature" from the list
    - select "Manage optional features" to go to the Setting App.
    - click on "OpenSSH Client" and uninstall

    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Packge` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.

    @@ -63,7 +66,7 @@ In order for all of the commands in this tutorial to work you will need at least
    If you for some reason can't upgrade powershell this tutorial provides subset of alternative commands that will work
    except posh-git which requires powershell version 5.

    To grab and install latest PowerShell core follow the this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)
    To grab and install latest PowerShell core follow this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)

    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation oportunities
    as explained on this link:
    @@ -92,14 +95,27 @@ Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.

    to see package sources first run:\
    `Get-PackageSource`
    To see package sources first run:

    To set nuget.org as trusted run:\
    `Set-PackageSource -Name nuget.org -Trusted`
    ```powershell
    Get-PackageSource
    ```

    To set nuget.org as trusted run:

    ```powershell
    Set-PackageSource -Name nuget.org -Trusted
    ```

    More information about [NuGet provider](https://docs.microsoft.com/en-us/nuget/what-is-nuget)

    To set PSGallery as trusted run:\
    `Set-PSRepository -Name PSGallery -InstallationPolicy Trusted `
    To set PSGallery as trusted run:

    ```powershell
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
    ```

    More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/powershell/gallery/overview)

    8. Next logical step is to install/update prerequisites.

    @@ -109,21 +125,42 @@ Let's first check if we have required NuGet package provider installed:
    Get-PackageProvider
    ```

    If NuGet is not listed, or installed regarldess run new Powershell (Admin) instance and install it (or update with -Force),
    If NuGet is not listed (or to check if it's out of date) find out if it's possible to install/update it:

    ```powershell
    Find-PackageProvider -Name "NuGet" -AllVersions
    ```

    If NuGet is out of date or not installed run new Powershell (Admin) instance and install it (or update with `-Force` switch),

    ```powershell
    Install-PackageProvider -Name NuGet
    ```

    Restart administrative PowerShell and then we also need a *new* PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you should get an error:
    Restart administrative PowerShell and then we also need to update PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you should get an error:

    To see currently installed versions:

    ```powershell
    Get-Module -ListAvailable -Name PowerShellGet
    ```

    To install new version on top of that is preinstalled:

    ```powershell
    Install-Module -Name PowerShellGet -Force
    ```

    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 commands before exeuting them, and make sure you use `-Force`
    To update existing PowerShellGet: (the one you personally already installed with `Install-Module`)

    ```powershell
    Update-Module -Name PowerShellGet
    ```

    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 sets of commands before exeuting them,
    and make sure you use `-Force` with `Install-Module`

    9. Next restart admin powershell and search for availabe chocolatey versions:
    9. Next again restart admin powershell and search for availabe chocolatey versions:

    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.

    @@ -374,7 +411,6 @@ repos.
    More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options

    **NOTE:** If you have at least PowerShell 5 with PackageManagement installed, you can use the package manager to install posh-git for you.
    More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/powershell/gallery/overview)

    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:

  25. metablaster revised this gist Aug 11, 2020. 1 changed file with 76 additions and 36 deletions.
    Original file line number Diff line number Diff line change
    @@ -54,6 +54,7 @@ also these steps have been tested on Windows 10 only

    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:

    ```powershell
    $PSVersionTable.PSVersion
    ```
    @@ -62,29 +63,31 @@ In order for all of the commands in this tutorial to work you will need at least
    If you for some reason can't upgrade powershell this tutorial provides subset of alternative commands that will work
    except posh-git which requires powershell version 5.

    To grab and install latest PowerShell core follow the this link [Get PowerShell](https://github.com/PowerShell/PowerShell#get-powershell)
    To grab and install latest PowerShell core follow the this link [Get PowerShell Core](https://github.com/PowerShell/PowerShell/releases)

    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation oportunities
    as explained in first link:
    as explained on this link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)

    5. Before you're able to run PowerShell scripts on your machine, you need to set your local ExecutionPolicy to RemoteSigned
    More about [PowerShell Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6)
    More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6)

    6. Open up Powershell (Admin) and check current execution policy
    6. Open up Powershell (Admin) and check current execution policy:

    ```powershell
    Get-ExecutionPolicy
    ```

    **NOTE:** PowerShell Core defaults to `RemoteSigned` while Windows PowerShell defaults to `Restricted`

    if it's not RemoteSigned change execution policy:

    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    7. Because we'll install some modules, you might want set NuGet package source as trusted, also you might want to do it for both Administrative and standard account (by using respective PowerShell for each user).
    7. Because we'll install some modules, you might want to set NuGet and PSGalery package sources as trusted, also you might want to do it for both Administrative and standard account (by opening respective PowerShell for each user).

    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.
    @@ -100,20 +103,24 @@ To set PSGallery as trusted run:\

    8. Next logical step is to install/update prerequisites.

    Let's first check if we have required NuGet package provider installed
    Let's first check if we have required NuGet package provider installed:

    ```powershell
    Get-PackageProvider
    ```

    If NuGet is not listed, or installed regarldess run new Powershell (Admin) instance and install it (or update with -Force),

    ```powershell
    Install-PackageProvider -Name NuGet
    ```

    Restart administrative PowerShell and then we also need a *new* PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you get an error:
    Restart administrative PowerShell and then we also need a *new* PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you should get an error:

    ```powershell
    Install-Module -Name PowerShellGet -Force
    ```

    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 commands before exeuting them, and make sure you use `-Force`

    9. Next restart admin powershell and search for availabe chocolatey versions:
    @@ -128,11 +135,12 @@ Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I preffer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)\
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based on Microsoft fork on github, the difference is that this one will also give us the option to install windows service for ssh-agent.\
    To input more parameters see previous openssh link, we use -pre to get latest prerelese.
    To input more parameters see previous openssh link, we use `-pre` to get latest prerelese.

    **OPTION 1: Using Install-Package**
    To download chocolatey, replace `RequiredVersion` option\
    with version obtained from `Find-Package` above
    with version obtained from `Find-Package` above:

    ```powershell
    Install-Package -Name chocolatey -ProviderName NuGet -RequiredVersion x.x.x
    ```
    @@ -153,45 +161,52 @@ Finaly to install OpenSSH, restart administrative PowerShell and run:\
    **OPTION 2: Using nuget.exe**
    This is alternative method to install chocolatey and OpenSHH:

    Get latest `nuget.exe` from https://www.nuget.org/downloads, put it somewhere for example `C:\tools`
    Get latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads), put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.

    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com/).\
    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com).\
    **NOTE:** if you wish to install chocolately somewhere else update first command, and esure choosen path is in `%PATH%` evironment variable.

    ```powershell
    cd C:\tools
    nuget install chocolatey
    cd choco*\tools
    & .\chocolateyInstall.ps1
    choco install openssh -pre --package-parameters="/SSHAgentFeature"
    ```
    10. For option 1, `Install-Package` will download chocolatey into `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\

    10. For option 1, `Install-Package` will download chocolatey into:\
    `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\
    For option2: nuget.exe will temporary download chocolatey to `C:\tools\chocolatey.x.x.x`.

    In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and OpenSSH with service configuration will be installed into `C:\Program Files\OpenSSH-Win64`.

    11. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.

    12. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing:

    ```powershell
    where.exe ssh
    where.exe gpg
    ```

    Now start telling git about our setup: (btw. hard to tell why this silly sintax for paths)

    ```powershell
    git config --global --replace-all core.sshCommand "'C:\Program Files\OpenSSH-Win64\ssh.exe'"
    git config --global --replace-all gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    ```

    And to verify these commands are input corectly:
    ```

    ```powershell
    git config --global --edit
    ```

    The input must look like this:
    The input must look like this (I'm showing this so that tutorial changes don't mess up with expected result):

    ```
    [core]
    @@ -215,10 +230,10 @@ them with gpg4win to sign commits, then issue following commands to move entry c
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    ```

    If you have existing key somewhere else (ex. backup on USB) then import them with cleopatra.
    If you have existing key somewhere else (ex. backup on USB) then import them with Kleopatra.

    14. Otherwise if you don't have any gpg keys at all then generate new keys.
    you can generate gpg keys with cleopatra that comes with gpg4win or you can do the same in powershell by typing:
    you can generate gpg keys with Kleopatra that comes with gpg4win or you can do the same in powershell by typing:

    ```powershell
    gpg --default-new-key-algo rsa4096 --gen-key
    @@ -230,7 +245,7 @@ At the prompt, specify your options, email, password etc. when asked.
    ```powershell
    gpg --list-secret-keys --keyid-format LONG
    ```
    From the list of GPG keys, copy the GPG key ID you'd like to use. In following example, the GPG key ID is `3AA5C34371567BD2`
    From the list of GPG keys, copy the GPG key ID you'd like to use. In the following example, the GPG key ID is `3AA5C34371567BD2`

    example:
    ```powershell
    @@ -250,12 +265,15 @@ git config --global user.signingkey 3AA5C34371567BD2
    git config --global commit.gpgsign true
    ```
    Export public key to clipboard (Note taht Set-Clipboard cmdlet works only with newer powershell versions)
    if Set-Clipboard doesn't work export the the key using cmd, as shown below
    if Set-Clipboard doesn't work export the the key using cmd, as shown in the second command:

    ```powershell
    gpg --armor --export 3AA5C34371567BD2 | Set-Clipboard
    ```

    Version to export public key to clipboard if `Set-Clipboard` doesn't work:
    ```

    ```powershell
    gpg --armor --export 3AA5C34371567BD2 > gpgkey.txt
    cmd
    clip < gpgkey.txt
    @@ -277,24 +295,29 @@ This accepts the default file location, also specify new password for the key.

    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:\
    **NOTE:** I provide command for this because on server platforms it might not be possible with mouse.

    ```powershell
    mkdir $env:USERPROFILE\.ssh
    ```

    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.shh` folder.

    Once you have your keys in default location, add private key to ssh-agent
    Once you have your keys in default location, add your private key to ssh-agent:

    ```powershell
    ssh-add $env:USERPROFILE\.ssh\id_rsa
    ```

    **NOTE:** `ssh-add` without arguments adds the default keys `~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa. ~/ssh/id_ed25519, and ~/.ssh/identity` if they exist.

    Copy ssh public key to clipboard (again if `Set-Clipboard` doesn't work see version below)
    Copy ssh public key to clipboard (again if `Set-Clipboard` doesn't work see second command below)

    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub | Set-Clipboard
    ```

    Version to copy ssh public key to clipboard if `˙Set-Clipboard` doesn't work:

    ```powershell
    Get-Content $env:USERPROFILE\.ssh\id_rsa.pub > sshkey.txt
    cmd
    @@ -306,30 +329,38 @@ del sshkey.txt
    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.

    17. You also want to tell git about yourself:

    ```powershell
    git config --global user.name "your name"
    git config --global user.name "your name or username"
    git config --global user.email [email protected]
    ```

    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 1h so that you don't have to input
    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 2h so that you don't have to input
    gpg key password every time you commit!

    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:

    ```powershell
    New-Item -Path $(Write-Output $env:appdata\gnupg\gpg-agent.conf) -ItemType "file"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "default-cache-ttl 7200"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "max-cache-ttl 10800"
    ```

    To set pin entry to wait max. 1 minute for input set:

    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    ```

    To have gpg-agent log it's activity about pasword caching (debug number 6), substitute "your_username" in the command below with your actual user name.

    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "log-file C:\Users\<your_username>\AppData\Roaming\gnupg\gpg-agent.log"
    ```

    Next we stop gpg-agent and start it again:

    ```powershell
    gpgconf --kill gpg-agent
    gpgconf --launch gpg-agent
    @@ -347,45 +378,54 @@ More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/pow

    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:

    First we need to check and if necesary set execution policy for current user:
    Open up Powershell (standard user) and check current execution policy
    First we need to check and if necesary set execution policy for current user,
    Open up Powershell (standard user) and check current execution policy:

    ```powershell
    Get-ExecutionPolicy
    ```

    if it's not RemoteSigned change execution policy:

    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    If you never installed posh-git then:

    ```powershell
    PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease -Force
    PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease
    ```
    Otherwise:

    Otherwise to update existing one:

    ```powershell
    PowerShellGet\Update-Module posh-git
    ```

    Finally import module and tell powershell to import it every next time:
    Finally import module and tell powershell to import it each next time:

    ```powershell
    Import-Module posh-git
    Add-PoshGitToProfile -AllHosts
    ```

    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`

    20. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell default its `Restricted` and for PowerShell Core it is `RemoteSigned`
    For Windows PowerShell, default its `Restricted` and for PowerShell Core it is `RemoteSigned`

    ## FINAL STEP AND YOUR OPINION:
    That's it reboot system and start testing your git setup with powershell, try experimenting push/pull/commit etc.., but basically you should be now able to work with git in powersehll where ssh-agent will not ask you for password because it runs as service on windows, and also gpg-agent will ask you for password only once per terminal session!
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even thouh git will use your new setup the terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environemnt there are two ssh programs resulting in conflict.
    ## FINAL STEP AND YOUR OPINION:
    That's it reboot system (if needed) and start testing your git setup with PowerShell, try experimenting push/pull/commit etc.., but basically you should now be able to work with git in powersehll, where ssh-agent will not ask you for password because it runs as service on Windows, and also gpg-agent will ask you for password only once per terminal session!

    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even thouh git will use your new setup the msys terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environemnt there are two ssh programs resulting in conflict.

    If you encounter problems or have suggestion please report.
    enjoy :grinning:

    happy coding! :grinning:

    ~metablaster
  26. metablaster revised this gist Aug 10, 2020. 1 changed file with 6 additions and 3 deletions.
    Original file line number Diff line number Diff line change
    @@ -119,7 +119,10 @@ If you get an error such as "Unable to find module providers" in Windows PowerSh
    9. Next restart admin powershell and search for availabe chocolatey versions:

    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.
    `Find-Package chocolatey -MinimumVersion 0.10.14`

    ```powershell
    Find-Package chocolatey -MinimumVersion 0.10.14`
    ```

    Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I preffer the easy way.
    @@ -273,7 +276,7 @@ When you're prompted to "Enter a file in which to save the key," press Enter.
    This accepts the default file location, also specify new password for the key.

    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:\
    **NOTE** I provide command for this because on server platforms it might not be possible with mouse.
    **NOTE:** I provide command for this because on server platforms it might not be possible with mouse.
    ```powershell
    mkdir $env:USERPROFILE\.ssh
    ```
    @@ -321,7 +324,7 @@ To set pin entry to wait max. 1 minute for input set:
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    ```
    To have gpg-agent log it's activity about pasword caching (debug number 6):
    To have gpg-agent log it's activity about pasword caching (debug number 6), substitute "your_username" in the command below with your actual user name.
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "log-file C:\Users\<your_username>\AppData\Roaming\gnupg\gpg-agent.log"
  27. metablaster revised this gist Aug 10, 2020. 1 changed file with 5 additions and 5 deletions.
    Original file line number Diff line number Diff line change
    @@ -272,7 +272,7 @@ ssh-keygen -t rsa -b 4096 -C "[email protected]"
    When you're prompted to "Enter a file in which to save the key," press Enter.
    This accepts the default file location, also specify new password for the key.

    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:
    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:\
    **NOTE** I provide command for this because on server platforms it might not be possible with mouse.
    ```powershell
    mkdir $env:USERPROFILE\.ssh
    @@ -302,13 +302,13 @@ del sshkey.txt

    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.

    16. You also want to tell git about yourself:
    17. You also want to tell git about yourself:
    ```powershell
    git config --global user.name "your name"
    git config --global user.email [email protected]
    ```

    17. next thing to do is to make `gpg-agent` cache your password longer, say for at least 1h so that you don't have to input
    18. next thing to do is to make `gpg-agent` cache your password longer, say for at least 1h so that you don't have to input
    gpg key password every time you commit!

    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:
    @@ -335,7 +335,7 @@ gpgconf --launch gpg-agent
    you can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    Above numbers mean, default-cache 2h, max-cache 3h and pin entry 1min.

    18. now last thing to do is to install posh-git module so that you get nice color prompt in powershell when working with git
    19. now last thing to do is to install posh-git module so that you get nice color prompt in powershell when working with git
    repos.
    More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options

    @@ -372,7 +372,7 @@ Add-PoshGitToProfile -AllHosts
    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`

    19. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    20. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell default its `Restricted` and for PowerShell Core it is `RemoteSigned`

    ## FINAL STEP AND YOUR OPINION:
  28. metablaster revised this gist Aug 10, 2020. 1 changed file with 14 additions and 6 deletions.
    Original file line number Diff line number Diff line change
    @@ -222,7 +222,7 @@ gpg --default-new-key-algo rsa4096 --gen-key
    ```
    At the prompt, specify your options, email, password etc. when asked.

    15. Now it's time to gather information and tell git about our keys:
    15. Now it's time to gather information and tell git about our gpg keys:

    ```powershell
    gpg --list-secret-keys --keyid-format LONG
    @@ -239,7 +239,7 @@ sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
    uid [ultimate] your_username (key for github) <[email protected]>
    ssb 4096R/42B317FD4BA89E7A 2017-09-13 [E] [expires: 2017-09-12]
    ```
    Paste the text below, substituting in the GPG key ID you'd like to use. In this example, the GPG key ID is `3AA5C34371567BD2`
    Paste the text below, substituting in the GPG key ID you'd like to use.
    Tell git about your signing key, and tell it that you want to sign all commits by default:

    ```powershell
    @@ -262,17 +262,25 @@ del gpgkey.txt

    Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key** and pres **CTRL+V** into box to paste the key.

    15. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    are stored because all ssh programs write keys to same directory that is `~\.ssh`
    16. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    are (will be) stored because all ssh programs write keys to same directory that is `~\.ssh`

    type following to generate keys:
    type following to generate new keys:
    ```powershell
    ssh-keygen -t rsa -b 4096 -C "[email protected]"
    ```
    When you're prompted to "Enter a file in which to save the key," press Enter.
    This accepts the default file location, also specify new password for the key.

    Add private key to ssh-agent
    If your ssh keys are somewhere else, (ex. backed up on USB), you'll first need to create a new folder for them:
    **NOTE** I provide command for this because on server platforms it might not be possible with mouse.
    ```powershell
    mkdir $env:USERPROFILE\.ssh
    ```

    copy/paste `id_rsa` and `id_rsa.pub` from your backup into new `~\.shh` folder.

    Once you have your keys in default location, add private key to ssh-agent
    ```powershell
    ssh-add $env:USERPROFILE\.ssh\id_rsa
    ```
  29. metablaster revised this gist Aug 10, 2020. 1 changed file with 46 additions and 29 deletions.
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@ you wan't all that in powershell then you are likely to get into a lot of troubl
    Other uses of this setup include use of git with custom ssh and gpg for what ever reason, or if you just wan't to be able to cache keys in a more efficient ways.

    the biggest problem is that ssh that comes with git doesn't run ssh-agent automatically, posh-git doesn't start
    ssh-agent properly at the time of writing, (maybe some new version in the future will), because there is a conflich between
    ssh-agent properly at the time of writing, (maybe some new version in the future will), because there is a conflict between
    openSSH that comes with windows and ssh that comes with git, so the alternative way is to use OpenSSH that comes bundled
    with Windows 10.
    For more information see [OpenSSH in Windows](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview)
    @@ -30,27 +30,27 @@ signature warning when doing push (at least on Windows 1903), so we need to inst
    note that even if posh-git manages to start ssh it still won't be perfect for our key-caching goal because ssh that comes with git
    doesn't offer windows service!

    I won't go into details to much as to providing technicall details why default setup doesn't work,
    I won't go into details too much as to providing technicall details why default setup doesn't work,
    because it would take a lot of explanation, and since you're reading this you might already know that!


    ## TUTORIAL STEPS:

    **NOTE:** Portion of the steps here are copied from github.com tutorial but updated to reflect powershell usage, and some
    stuff has been removed because it's irrelevant with our world class setup.
    stuff has been removed because it's irrelevant with our setup.

    Also some of the conent is copied from git-scm.com and other sites, the point is that all these informations are now assembled
    here in one place for complete tutorial, hence the name "Ultimate tutorial"
    Also some of the conent is copied from git-scm.com and other sites, the point is that all this information is now assembled
    here in one place for a complete tutorial.

    **NOTE:** All of the commands below are executed in powershell,
    also these steps have been tested on Windows 10 only

    1. First if you didn't already download and install [gpg4win](https://www.gpg4win.org/download.html) and [git](https://git-scm.com/)
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows, log into administrator account then
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows, log into Administrative account then

    **Hit Start > Type "Optional Feature" > go to the Setting App. Check the "OpenSSH Client" and uninstall**

    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Packge` version and if that does not work then `nuget.exe` option because these seem to be the most practical options.
    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Packge` version and if that doesn't work then `nuget.exe` option because these seem to be the most practical options.

    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:
    @@ -62,9 +62,9 @@ In order for all of the commands in this tutorial to work you will need at least
    If you for some reason can't upgrade powershell this tutorial provides subset of alternative commands that will work
    except posh-git which requires powershell version 5.

    To grab and install latest powershell follow the this link [Get PowerShell](https://github.com/PowerShell/PowerShell#get-powershell)
    To grab and install latest PowerShell core follow the this link [Get PowerShell](https://github.com/PowerShell/PowerShell#get-powershell)

    Alternativelly you can grab zipped powershell installer as windows update, but with some restricted installation oportunities
    Otherwise if you need to update Windows PowerShell then grab zipped powershell installer as windows update, but with some restricted installation oportunities
    as explained in first link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)

    @@ -84,36 +84,41 @@ if it's not RemoteSigned change execution policy:
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    7. Next logical step is to install/update prerequisites.
    7. Because we'll install some modules, you might want set NuGet package source as trusted, also you might want to do it for both Administrative and standard account (by using respective PowerShell for each user).

    **NOTE:** commands for nuget.org (NuGet provider) in this step and steps 8 and 9 that follow may fail in PowerShell core, and the workaround is not worth spending time, if your Core is up to date you're fine!
    I'll let you know the alternative options, for now just skip "NuGet" steps if it doesn't work.

    to see package sources first run:\
    `Get-PackageSource`

    To set nuget.org as trusted run:\
    `Set-PackageSource -Name nuget.org -Trusted`

    To set PSGallery as trusted run:\
    `Set-PSRepository -Name PSGallery -InstallationPolicy Trusted `

    8. Next logical step is to install/update prerequisites.

    Let's first check if we have required NuGet package provider installed
    ```powershell
    Get-PackageProvider
    ```
    If NuGet is not listed, or installed regarldess run new Powershell (Admin) instance and install it (or update with -Force):
    If NuGet is not listed, or installed regarldess run new Powershell (Admin) instance and install it (or update with -Force),

    ```powershell
    Install-PackageProvider -Name NuGet
    ```

    Restart restart administrative PowerShell and then we also need a *new* PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you get an error:
    Restart administrative PowerShell and then we also need a *new* PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you get an error:
    ```powershell
    Install-Module -Name PowerShellGet -Force
    ```
    If you get an error such as "Unable to find module providers" restart administrative powershell for each of these 2 commands before exeuting them, and make sure you use `-Force`

    8. You may want set NuGet package source as trusted:

    to see package sources first run:\
    `Get-PackageSource`

    To set nuget.org as trusted run:\
    `Set-PackageSource -Name nuget.org -Trusted`

    To set PSGallery as trusted run:\
    `Set-PSRepository -Name PSGallery -InstallationPolicy Trusted `
    If you get an error such as "Unable to find module providers" in Windows PowerShell (in core it might not work anyway) restart administrative powershell for each of these 2 commands before exeuting them, and make sure you use `-Force`

    9. Next restart admin powershell and search for availabe chocolatey versions:

    **NOTE:** below command may fail in PowerShell core, if so there is "option 2" for you.
    `Find-Package chocolatey -MinimumVersion 0.10.14`

    Install chocolatey by using either option 1 or option 2:\
    @@ -183,8 +188,16 @@ And to verify these commands are input corectly:
    git config --global --edit
    ```

    The input must look like this:

    ```
    [core]
    sshCommand = 'C:\\Program Files\\OpenSSH-Win64\\ssh.exe'
    [gpg]
    program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe
    ```

    **NOTE:** above paths are pointing git to use gpg4win executalbe of gpg and our fresh installed openSSH portable as ssh program
    and also tells git to sign all commits by default

    13. Now everything is set up, and it's time to setup the keys!

    @@ -199,15 +212,18 @@ them with gpg4win to sign commits, then issue following commands to move entry c
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    ```

    14. Otherwise if you don't have any keys on your system generate new gpg keys (goto setp 13 to generate only ssh keys).
    If you have existing key somewhere else (ex. backup on USB) then import them with cleopatra.

    14. Otherwise if you don't have any gpg keys at all then generate new keys.
    you can generate gpg keys with cleopatra that comes with gpg4win or you can do the same in powershell by typing:

    ```powershell
    gpg --default-new-key-algo rsa4096 --gen-key
    ```
    At the prompt, specify your options, email, password etc. when asked.

    Now list the key(s)
    15. Now it's time to gather information and tell git about our keys:

    ```powershell
    gpg --list-secret-keys --keyid-format LONG
    ```
    @@ -224,7 +240,8 @@ uid [ultimate] your_username (key for github) <[email protected]
    ssb 4096R/42B317FD4BA89E7A 2017-09-13 [E] [expires: 2017-09-12]
    ```
    Paste the text below, substituting in the GPG key ID you'd like to use. In this example, the GPG key ID is `3AA5C34371567BD2`
    Tell git about your signing key
    Tell git about your signing key, and tell it that you want to sign all commits by default:

    ```powershell
    git config --global user.signingkey 3AA5C34371567BD2
    git config --global commit.gpgsign true
    @@ -353,7 +370,7 @@ For Windows PowerShell default its `Restricted` and for PowerShell Core it is `R
    ## FINAL STEP AND YOUR OPINION:
    That's it reboot system and start testing your git setup with powershell, try experimenting push/pull/commit etc.., but basically you should be now able to work with git in powersehll where ssh-agent will not ask you for password because it runs as service on windows, and also gpg-agent will ask you for password only once per terminal session!

    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even thouh git will use your new setup the terminal it self continues to use old settings and variables and ssh-agent will most like not cache your keys because inside msys terminal environemnt there are two ssh programs resulting in conflict.
    **NOTE:** Now Treat your msys terminal that comes with git as obsolete on your system, you have no reason to use it anymore, because even thouh git will use your new setup the terminal it self continues to use old settings and variables and ssh-agent will most likely not cache your keys because inside msys terminal environemnt there are two ssh programs resulting in conflict.


    If you encounter problems or have suggestion please report.
  30. metablaster revised this gist Jun 20, 2020. 1 changed file with 128 additions and 49 deletions.
    Original file line number Diff line number Diff line change
    @@ -42,22 +42,15 @@ stuff has been removed because it's irrelevant with our world class setup.
    Also some of the conent is copied from git-scm.com and other sites, the point is that all these informations are now assembled
    here in one place for complete tutorial, hence the name "Ultimate tutorial"

    **NOTE:** All of the commands below are executed in powershell!
    also these steps has been tested on Windows 10 and Windows 7
    **NOTE:** All of the commands below are executed in powershell,
    also these steps have been tested on Windows 10 only

    1. First if you didn't already download and install [gpg4win](https://www.gpg4win.org/download.html) and [git](https://git-scm.com/)
    2. Windows 10 only step: next we need to get rid of faulty openSSH that comes with windows, log into administrator account then

    **Hit Start > Type "Optional Feature" > go to the Setting App. Check the "OpenSSH Client" and uninstall**

    3. grab latest `nuget.exe` from https://www.nuget.org/downloads, put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable

    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com/),
    you can of course build openssh from source and exclude nuget.exe and chocolatey but I preffer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)
    There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) but we use `nuget.exe`
    option because that is what worked for me.
    3. There are multiple ways to install chocolatey as explained [here](https://chocolatey.org/docs/installation) we'll use `Install-Packge` version and if that does not work then `nuget.exe` option because these seem to be the most practical options.

    4. If you are running an older version of windows such as Windows 7 it's possible your powershell is pretty old
    so let's first check powershell version, Open up powershell and type:
    @@ -75,7 +68,7 @@ Alternativelly you can grab zipped powershell installer as windows update, but w
    as explained in first link:
    [Installing Windows PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6)

    5. Before youre able to run PowerShell scripts on your machine, you need to set your local ExecutionPolicy to RemoteSigned
    5. Before you're able to run PowerShell scripts on your machine, you need to set your local ExecutionPolicy to RemoteSigned
    More about [PowerShell Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6)
    More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6)

    @@ -84,26 +77,94 @@ More about [PowerShell ExecutionPolicy](https://docs.microsoft.com/en-us/powersh
    Get-ExecutionPolicy
    ```

    **NOTE:** PowerShell Core defaults to `RemoteSigned` while Windows PowerShell defaults to `Restricted`

    if it's not RemoteSigned change execution policy:
    ```powershell
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```
    7. next in same admin powershell install chocolatey, acept prompt and reverse execution policy to default:
    (note: if you wish to install chocolately somewhere else update first command, and esure choosen path is in `%PATH%` evironment variable):

    7. Next logical step is to install/update prerequisites.

    Let's first check if we have required NuGet package provider installed
    ```powershell
    Get-PackageProvider
    ```
    If NuGet is not listed, or installed regarldess run new Powershell (Admin) instance and install it (or update with -Force):
    ```powershell
    Install-PackageProvider -Name NuGet
    ```

    Restart restart administrative PowerShell and then we also need a *new* PowerShellGet version which is required for latest posh-git, this is possible to install only with `-Force` switch as explained [here](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7), otherwise you get an error:
    ```powershell
    Install-Module -Name PowerShellGet -Force
    ```
    If you get an error such as "Unable to find module providers" restart administrative powershell for each of these 2 commands before exeuting them, and make sure you use `-Force`

    8. You may want set NuGet package source as trusted:

    to see package sources first run:\
    `Get-PackageSource`

    To set nuget.org as trusted run:\
    `Set-PackageSource -Name nuget.org -Trusted`

    To set PSGallery as trusted run:\
    `Set-PSRepository -Name PSGallery -InstallationPolicy Trusted `

    9. Next restart admin powershell and search for availabe chocolatey versions:

    `Find-Package chocolatey -MinimumVersion 0.10.14`

    Install chocolatey by using either option 1 or option 2:\
    **NOTE:** You can of course build openssh from source and exclude nuget.exe and chocolatey but I preffer the easy way.
    if you wish to build it from source grab ported sources here: [PowerShell/openssh-portable](https://github.com/PowerShell/openssh-portable)\
    **NOTE:** We'll install [this openssh](https://chocolatey.org/packages/openssh) which is based on Microsoft fork on github, the difference is that this one will also give us the option to install windows service for ssh-agent.\
    To input more parameters see previous openssh link, we use -pre to get latest prerelese.

    **OPTION 1: Using Install-Package**
    To download chocolatey, replace `RequiredVersion` option\
    with version obtained from `Find-Package` above
    ```powershell
    Install-Package -Name chocolatey -ProviderName NuGet -RequiredVersion x.x.x
    ```

    Next to install chocolatey do:
    `Initialize-Chocolatey`

    this should finish installation, if this does not work then:\
    **NOTE:** update `cd` command to match chocolatey version
    ```powershell
    cd "C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.0.10.14\tools"
    `& .\chocolateyInstall.ps1
    ```

    Finaly to install OpenSSH, restart administrative PowerShell and run:\
    `choco install openssh -pre --package-parameters="/SSHAgentFeature"`

    **OPTION 2: Using nuget.exe**
    This is alternative method to install chocolatey and OpenSHH:

    Get latest `nuget.exe` from https://www.nuget.org/downloads, put it somewhere for example `C:\tools`
    and add `C:\tools` (or what ever path you choose) to `PATH` environment variable.

    **NOTE:** we need `nuget.exe` in `PATH` to install [chocolatey](https://chocolatey.org/), and we need chocolatey because it will let us install [openssh](https://www.openssh.com/).\
    **NOTE:** if you wish to install chocolately somewhere else update first command, and esure choosen path is in `%PATH%` evironment variable.
    ```powershell
    cd C:\tools
    nuget install chocolatey
    cd choco*\tools
    & .\chocolateyInstall.ps1
    choco install openssh --package-parameters="/SSHAgentFeature"
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Restricted
    choco install openssh -pre --package-parameters="/SSHAgentFeature"
    ```
    8. the above commands will temporary download chocolatey to `C:\tools` and install openssh with service configuration into
    `C:\Program Files\OpenSSH-Win64`, chocolately fill finally be installed into `%USERPROFILE%\chocolatey.x.x.x`
    10. For option 1, `Install-Package` will download chocolatey into `C:\Program Files\PackageManagement\NuGet\Packages\chocolatey.x.x.x`.\
    For option2: nuget.exe will temporary download chocolatey to `C:\tools\chocolatey.x.x.x`.

    9. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.
    In both cases chocolately will be installed into `%PROGRAMDATA%\chocolatey` and OpenSSH with service configuration will be installed into `C:\Program Files\OpenSSH-Win64`.

    10. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    11. now open `services.msc` as Administrator and make sure `ssh-agent` service is started and set to automatic startup.

    12. close Admin powershell and start new powershell instance (as standard user, if your acc isn't admin of course)
    Please first ensure that below ssh and gpg paths are correct paths on your system, and if not update as needed, for example,
    if you installed gpg4win or openSSH somewhere else.
    You can verify installation path by typing
    @@ -112,17 +173,20 @@ where.exe ssh
    where.exe gpg
    ```

    Now start telling git about our setup:
    Now start telling git about our setup: (btw. hard to tell why this silly sintax for paths)
    ```powershell
    git config --global core.sshCommand = "C:\\Program Files\\OpenSSH-Win64\\ssh.exe"
    git config --global gpg.program = "C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe"
    git config --global commit.gpgsign true
    git config --global --replace-all core.sshCommand "'C:\Program Files\OpenSSH-Win64\ssh.exe'"
    git config --global --replace-all gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    ```
    And to verify these commands are input corectly:
    ```
    git config --global --edit
    ```

    **NOTE:** above paths are pointing git to use gpg4win executalbe of gpg and our fresh installed openSSH portable as ssh program
    and also tells git to sign all commits by default

    11. Now everything is set up, and it's time to setup the keys!
    13. Now everything is set up, and it's time to setup the keys!

    If you have existing gpg keys made by gpg4win in `%appdata%\gnupg` which you would like to backup first (because we might override
    them) then issue the following command:
    @@ -135,7 +199,7 @@ them with gpg4win to sign commits, then issue following commands to move entry c
    robocopy $env:USERPROFILE\.gnupg $env:APPDATA\gnupg /MOVE /E
    ```

    12. Otherwise if you don't have any keys on your system generate new gpg keys (goto setp 13 to generate only ssh keys).
    14. Otherwise if you don't have any keys on your system generate new gpg keys (goto setp 13 to generate only ssh keys).
    you can generate gpg keys with cleopatra that comes with gpg4win or you can do the same in powershell by typing:

    ```powershell
    @@ -163,6 +227,7 @@ Paste the text below, substituting in the GPG key ID you'd like to use. In this
    Tell git about your signing key
    ```powershell
    git config --global user.signingkey 3AA5C34371567BD2
    git config --global commit.gpgsign true
    ```
    Export public key to clipboard (Note taht Set-Clipboard cmdlet works only with newer powershell versions)
    if Set-Clipboard doesn't work export the the key using cmd, as shown below
    @@ -180,7 +245,7 @@ del gpgkey.txt

    Now go to your **Github account > settings > SSH and GPG Keys > Add new GPG key** and pres **CTRL+V** into box to paste the key.

    13. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    15. same applies to ssh keys, if you don't have existing ones generate new ones, you don't need to worry about where keys
    are stored because all ssh programs write keys to same directory that is `~\.ssh`

    type following to generate keys:
    @@ -212,22 +277,48 @@ del sshkey.txt

    Now go to your **Github account > settings > SSH and GPG Keys > Add new SSH key** and pres **CTRL+V** into box to paste the key.

    14. next thing to do is to make `gpg-agent` cache your password longer, say for at least 1h so that you don't have to input
    16. You also want to tell git about yourself:
    ```powershell
    git config --global user.name "your name"
    git config --global user.email [email protected]
    ```

    17. next thing to do is to make `gpg-agent` cache your password longer, say for at least 1h so that you don't have to input
    gpg key password every time you commit!

    Next we'll create `gpg-agent.conf` in `%appdata%\gnupg` and input settings into a file:
    ```powershell
    New-Item -Path $(Write-Output $env:appdata\gnupg\gpg-agent.conf) -ItemType "file"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "default-cache-ttl 3600"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "dmax-cache-ttl 5400"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "default-cache-ttl 7200"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "max-cache-ttl 10800"
    ```
    To set pin entry to wait max. 1 minute for input set:
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "pinentry-timeout 60"
    ```
    To have gpg-agent log it's activity about pasword caching (debug number 6):
    ```powershell
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "debug 6"
    Add-Content $(Write-Output $env:appdata\gnupg\gpg-agent.conf) "log-file C:\Users\<your_username>\AppData\Roaming\gnupg\gpg-agent.log"
    ```
    Next we stop gpg-agent and start it again:
    ```powershell
    gpgconf --kill gpg-agent
    gpgconf --launch gpg-agent
    ```

    you can adjust these numbers which represent for how many seconds gpg-agent will cache password
    you can adjust these numbers which represent for how many seconds gpg-agent will cache password.\
    Above numbers mean, default-cache 2h, max-cache 3h and pin entry 1min.

    15. now last thing to do is to install posh-git module so that you get nice color prompt in powershell when working with git
    18. now last thing to do is to install posh-git module so that you get nice color prompt in powershell when working with git
    repos.
    More about [posh-git](https://github.com/dahlbyk/posh-git) and it's options

    **NOTE:** If you have at least PowerShell 5 with PackageManagement installed, you can use the package manager to install posh-git for you.
    More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/powershell/gallery/overview)

    Close Administrative powershell and the other powershell too, to update environment and open a new user mode powershell, then install posh-git:

    First we need to check and if necesary set execution policy for current user:
    Open up Powershell (standard user) and check current execution policy
    ```powershell
    @@ -239,27 +330,13 @@ if it's not RemoteSigned change execution policy:
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    ```

    If you have at least PowerShell 5 with PackageManagement installed, you can use the package manager to install posh-git for you.
    More information about [PowerShell Gallery](https://docs.microsoft.com/en-us/powershell/gallery/overview)

    Let's first check if we have required NuGet package provider installed
    ```powershell
    Get-PackageProvider
    ```
    If NuGet is not listed run new Powershell (Admin) instance and install it:
    ```powershell
    Install-PackageProvider NuGet
    ```

    Close Administrative powershell and switch back to user mode powershell,
    then install posh-git:
    If you never installed posh-git then:
    ```powershell
    Install-Module posh-git -Scope CurrentUser
    PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease -Force
    ```
    If the command fails with an error like `Module 'PowerShellGet' was not installed by using Install-Module,`
    you’ll need to run another command first:
    Otherwise:
    ```powershell
    Install-Module PowerShellGet
    PowerShellGet\Update-Module posh-git
    ```

    Finally import module and tell powershell to import it every next time:
    @@ -270,6 +347,8 @@ Add-PoshGitToProfile -AllHosts
    **NOTE:** Keep in mind, that there are multiple $profile scripts. ex: one for the console and a separate one for the ISE.
    that's why we use `-AllHosts`

    19. Final step is to reverse/reset execution policy for both administrative and user mode PowerShell:\
    For Windows PowerShell default its `Restricted` and for PowerShell Core it is `RemoteSigned`

    ## FINAL STEP AND YOUR OPINION:
    That's it reboot system and start testing your git setup with powershell, try experimenting push/pull/commit etc.., but basically you should be now able to work with git in powersehll where ssh-agent will not ask you for password because it runs as service on windows, and also gpg-agent will ask you for password only once per terminal session!