Skip to content

Commit 30a05a9

Browse files
authored
Merge pull request #176 from virot/JMarkstrom-patch-7
Update Set-YubiKey-HOTP.ps1
2 parents b9f929c + 771651c commit 30a05a9

File tree

1 file changed

+87
-40
lines changed

1 file changed

+87
-40
lines changed

Docs/Cookbook/Set-YubiKey-HOTP.ps1

Lines changed: 87 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ It can configure either the short press slot (1) or long press slot (2).
88
The configuration includes options for sending TAB before the code and appending a carriage return.
99
If a YubiKey with the same serial number already exists in the CSV file, its entry will be updated.
1010
11-
.PARAMETER ShortPress
12-
Programs (H)OTP to YubiKey slot 1
13-
14-
.PARAMETER LongPress
15-
Programs (H)OTP to YubiKey slot 2
11+
.PARAMETER Slot
12+
YubiKey OTP slot to configure. Valid values are:
13+
- 1 or ShortPress: Programs (H)OTP to YubiKey slot 1 (Short Press)
14+
- 2 or LongPress: Programs (H)OTP to YubiKey slot 2 (Long Press)
1615
1716
.PARAMETER SendTabFirst
1817
Sends TAB before the passcode to navigate UI
@@ -26,25 +25,34 @@ Use 8 digits instead of 6 for the passcode
2625
.PARAMETER SecretFormat
2726
Secret format to use (Base32 or Hex)
2827
28+
.PARAMETER AccessCode
29+
New access code (12-character hex string) to protect the slot
30+
31+
2932
.EXAMPLE
30-
.\Set-YubiKey-HOTP.ps1 -ShortPress
31-
Programs HOTP to slot 1 (short press) on the YubiKey using Base32 format (default).
33+
.\Set-YubiKey-HOTP.ps1 -Slot 1
34+
Programs HOTP to slot 1 (Short Press) on the YubiKey using Base32 format (default).
3235
3336
.EXAMPLE
34-
.\Set-YubiKey-HOTP.ps1 -LongPress -SendTabFirst -AppendCarriageReturn
35-
Programs HOTP to slot 2 (long press) with TAB before the code and Enter after, using Base32 format.
37+
.\Set-YubiKey-HOTP.ps1 -Slot 1 -SendTabFirst -AppendCarriageReturn
38+
Programs HOTP to slot 1 (Short Press) with TAB before the code and Enter after, using Base32 format.
3639
3740
.EXAMPLE
38-
.\Set-YubiKey-HOTP.ps1 -ShortPress -Use8Digits
39-
Programs HOTP to slot 1 with 8-digit passcodes using Base32 format.
41+
.\Set-YubiKey-HOTP.ps1 -Slot 1 -Use8Digits
42+
Programs HOTP to slot 1 (Short Press) with 8-digit passcodes using Base32 format.
4043
4144
.EXAMPLE
42-
.\Set-YubiKey-HOTP.ps1 -ShortPress -SecretFormat Hex
43-
Programs HOTP to slot 1 using hex format (recommended for Cisco Duo and Ping Identity).
45+
.\Set-YubiKey-HOTP.ps1 -Slot 1 -SecretFormat Hex
46+
Programs HOTP to slot 1 (Short Press) using hex format (recommended for Cisco Duo and Ping Identity).
4447
4548
.EXAMPLE
46-
.\Set-YubiKey-HOTP.ps1 -LongPress -SecretFormat Hex -SendTabFirst -AppendCarriageReturn
47-
Programs HOTP to slot 2 using hex format with TAB and Enter, suitable for Cisco Duo.
49+
.\Set-YubiKey-HOTP.ps1 -Slot 1 -SecretFormat Hex -SendTabFirst -AppendCarriageReturn
50+
Programs HOTP to slot 1 (Short Press) using hex format with TAB and Enter, suitable for Cisco Duo.
51+
52+
.EXAMPLE
53+
.\Set-YubiKey-HOTP.ps1 -Slot 1 -AccessCode "010203040506"
54+
Programs HOTP to slot 1 (Short Press) with a new access code to protect the slot.
55+
4856
4957
.NOTES
5058
- Requires the powerShellYK module
@@ -53,6 +61,8 @@ Programs HOTP to slot 2 using hex format with TAB and Enter, suitable for Cisco
5361
- If a YubiKey with the same serial number is programmed again, its entry will be updated
5462
- After programming, prompts to program another YubiKey (Y/n)
5563
- For Cisco Duo and Ping Identity, use hex format with "-SecretFormat Hex"
64+
- Slot parameter accepts: ShortPress, LongPress, 1, or 2
65+
- Access codes are 12-character hex strings that protect slots from unauthorized configuration
5666
5767
.LINK
5868
https://github.com/virot/powershellYK/
@@ -67,7 +77,8 @@ function Set-YubiKeyHOTPConfig {
6777
[switch]$Use8Digits,
6878
[string]$CsvFilePath,
6979
[ValidateSet('Base32', 'Hex')]
70-
[string]$SecretFormat = 'Base32'
80+
[string]$SecretFormat = 'Base32',
81+
[string]$AccessCode
7182
)
7283

7384
# Connect to YubiKey
@@ -94,7 +105,28 @@ function Set-YubiKeyHOTPConfig {
94105
}
95106

96107
Write-Host "Configuring HOTP..." -ForegroundColor Yellow
97-
$result = Set-YubiKeyOTP -Slot $slot -HOTP -SendTabFirst:$SendTabFirst -AppendCarriageReturn:$AppendCarriageReturn -Use8Digits:$Use8Digits
108+
109+
# Build the Set-YubiKeyOTP command with access code parameters if provided
110+
$otpParams = @{
111+
Slot = $slot
112+
HOTP = $true
113+
Use8Digits = $Use8Digits
114+
}
115+
116+
# Add switch parameters only if they are present
117+
if ($SendTabFirst) {
118+
$otpParams.SendTabFirst = $true
119+
}
120+
121+
if ($AppendCarriageReturn) {
122+
$otpParams.AppendCarriageReturn = $true
123+
}
124+
125+
if ($AccessCode) {
126+
$otpParams.AccessCode = $AccessCode
127+
}
128+
129+
$result = Set-YubiKeyOTP @otpParams
98130

99131
# Create new configuration object
100132
$newConfig = [PSCustomObject]@{
@@ -109,14 +141,17 @@ function Set-YubiKeyHOTPConfig {
109141
$serialExists = $false
110142

111143
# Check if serial exists and update if found
112-
$updatedData = @($existingData | ForEach-Object {
113-
if ($_.Serial -eq $yubiKeyInfo.SerialNumber) {
114-
$serialExists = $true
115-
$newConfig
116-
} else {
117-
$_
118-
}
119-
})
144+
$updatedData = @()
145+
if ($existingData) {
146+
$updatedData = @($existingData | ForEach-Object {
147+
if ($_.Serial -eq $yubiKeyInfo.SerialNumber) {
148+
$serialExists = $true
149+
$newConfig
150+
} else {
151+
$_
152+
}
153+
})
154+
}
120155

121156
# If serial didn't exist, append the new config
122157
if (-not $serialExists) {
@@ -147,20 +182,14 @@ function Set-YubiKeyHOTPConfig {
147182

148183
# Main function with parameters
149184
function Set-YubiKeyHOTP {
150-
[CmdletBinding(DefaultParameterSetName = 'ShortPress')]
185+
[CmdletBinding()]
151186
param
152187
(
153188
[Parameter(Mandatory=$True,
154-
ParameterSetName = 'ShortPress',
155-
HelpMessage = "Programs (H)OTP to YubiKey slot 1")]
156-
[switch]
157-
$ShortPress,
158-
159-
[Parameter(Mandatory=$True,
160-
ParameterSetName = 'LongPress',
161-
HelpMessage = "Programs (H)OTP to YubiKey slot 2")]
162-
[switch]
163-
$LongPress,
189+
HelpMessage = "YubiKey OTP slot to configure (ShortPress, LongPress, 1, or 2)")]
190+
[ValidateSet('ShortPress', 'LongPress', '1', '2')]
191+
[string]
192+
$Slot,
164193

165194
[Parameter(Mandatory=$False,
166195
HelpMessage = "Sends TAB before the passcode to navigate UI")]
@@ -181,7 +210,14 @@ function Set-YubiKeyHOTP {
181210
HelpMessage = "Secret format to use (Base32 or Hex)")]
182211
[ValidateSet('Base32', 'Hex')]
183212
[string]
184-
$SecretFormat = 'Base32'
213+
$SecretFormat = 'Base32',
214+
215+
[Parameter(Mandatory=$False,
216+
HelpMessage = "New access code (12-character hex string)")]
217+
[ValidatePattern('^[0-9A-Fa-f]{12}$')]
218+
[string]
219+
$AccessCode
220+
185221
)
186222

187223
begin {
@@ -193,20 +229,31 @@ function Set-YubiKeyHOTP {
193229
Set-Content -Path $csvFilePath -Value "Serial,Secret,Counter,Length" -Encoding UTF8
194230
} else {
195231
Write-Debug "Found existing CSV file in the current directory. Will update if serial exists..."
232+
# Ensure the file has the correct headers
233+
$content = Get-Content -Path $csvFilePath -Raw
234+
if (-not $content -or -not $content.Contains("Serial,Secret,Counter,Length")) {
235+
Set-Content -Path $csvFilePath -Value "Serial,Secret,Counter,Length" -Encoding UTF8
236+
}
196237
}
197238
# Suppress informational messages
198239
$InformationPreference = 'SilentlyContinue'
199240

200241
# Determine which slot to configure
201-
$slot = if ($ShortPress) { [Yubico.YubiKey.Otp.Slot]::ShortPress } else { [Yubico.YubiKey.Otp.Slot]::LongPress }
242+
$slot = switch ($Slot) {
243+
'ShortPress' { [Yubico.YubiKey.Otp.Slot]::ShortPress }
244+
'LongPress' { [Yubico.YubiKey.Otp.Slot]::LongPress }
245+
'1' { [Yubico.YubiKey.Otp.Slot]::ShortPress }
246+
'2' { [Yubico.YubiKey.Otp.Slot]::LongPress }
247+
default { [Yubico.YubiKey.Otp.Slot]::ShortPress }
248+
}
202249

203250
# Program first YubiKey
204251
Clear-Host
205252
Write-Warning "Please insert a YubiKey NOW and press any key to continue:"
206253
[System.Console]::ReadKey() > $null
207254
Clear-Host
208255

209-
if (-not (Set-YubiKeyHOTPConfig -Slot $slot -SendTabFirst:$SendTabFirst -AppendCarriageReturn:$AppendCarriageReturn -Use8Digits:$Use8Digits -CsvFilePath $csvFilePath -SecretFormat $SecretFormat)) {
256+
if (-not (Set-YubiKeyHOTPConfig -Slot $slot -SendTabFirst:$SendTabFirst -AppendCarriageReturn:$AppendCarriageReturn -Use8Digits:$Use8Digits -CsvFilePath $csvFilePath -SecretFormat $SecretFormat -AccessCode $AccessCode)) {
210257
return
211258
}
212259

@@ -233,7 +280,7 @@ function Set-YubiKeyHOTP {
233280
[System.Console]::ReadKey() > $null
234281
Clear-Host
235282

236-
if (-not (Set-YubiKeyHOTPConfig -Slot $slot -SendTabFirst:$SendTabFirst -AppendCarriageReturn:$AppendCarriageReturn -Use8Digits:$Use8Digits -CsvFilePath $csvFilePath -SecretFormat $SecretFormat)) {
283+
if (-not (Set-YubiKeyHOTPConfig -Slot $slot -SendTabFirst:$SendTabFirst -AppendCarriageReturn:$AppendCarriageReturn -Use8Digits:$Use8Digits -CsvFilePath $csvFilePath -SecretFormat $SecretFormat -AccessCode $AccessCode)) {
237284
continue
238285
}
239286
}

0 commit comments

Comments
 (0)