Skip to content

Commit ef42942

Browse files
committed
Initial commit
0 parents  commit ef42942

13 files changed

+234
-0
lines changed

.github/FUNDING.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# These are supported funding model platforms
2+
3+
github: [alan-null]
4+
custom: ['https://www.paypal.com/paypalme/plocieniak']

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fake-UserAgent/data/user-agents.json
2+
Fake-UserAgent/data/user-agents.dat

Fake-UserAgent/Fake-UserAgent.psd1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
@{
3+
RootModule = 'Fake-UserAgent.psm1'
4+
ModuleVersion = '0.1.0'
5+
GUID = 'ef6d1c27-66ac-4f6c-8cc6-2bbae0f24543'
6+
Author = 'Alan Plocieniak'
7+
CompanyName = 'Alan Plocieniak'
8+
Copyright = '(c) 2025 Alan Plocieniak. All rights reserved.'
9+
Description = 'PowerShell module for generating random User Agents.'
10+
PowerShellVersion = '5.0'
11+
FunctionsToExport = '*'
12+
PrivateData = @{
13+
PSData = @{
14+
Tags = @('powershell', 'fake', 'ps', 'power-shell', 'fake-useragent', 'useragent', 'user', 'agent' )
15+
LicenseUri = 'https://github.com/PowerShellLibrary/Fake-UserAgent/blob/master/LICENSE.md'
16+
ProjectUri = 'https://github.com/PowerShellLibrary/Fake-UserAgent'
17+
}
18+
}
19+
}

Fake-UserAgent/Fake-UserAgent.psm1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
$Public = @( Get-ChildItem -Path $PSScriptRoot\Public -Recurse -Filter *.ps1 -ErrorAction SilentlyContinue )
2+
$Private = @( Get-ChildItem -Path $PSScriptRoot\Private -Recurse -Filter *.ps1 -ErrorAction SilentlyContinue )
3+
4+
Foreach ($import in @($Public + $Private)) {
5+
try {
6+
. $import.fullname
7+
}
8+
catch {
9+
Write-Error -Message "Failed to import function $($import.fullname): $_"
10+
}
11+
}
12+
Export-ModuleMember -Function $Public.Basename
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
function ConvertFrom-Gzip {
2+
Param (
3+
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
4+
[ValidateScript( { (Get-Item $_).Name.EndsWith(".gz") })]
5+
[System.IO.FileInfo]
6+
$InputObject,
7+
8+
[Parameter(Mandatory = $false)]
9+
[switch]
10+
$RemoveInputFile
11+
)
12+
Process {
13+
# Create a new file and open a filestream for it
14+
$NewFilename = $InputObject.FullName.Remove($InputObject.FullName.Length - $InputObject.Extension.Length)
15+
$DecompressedFileStream = [System.IO.File]::Create($NewFilename)
16+
17+
# Open the compressed file and copy the file to the decompressed stream
18+
$CompressedFileStream = $InputObject.OpenRead()
19+
$GZipStream = [System.IO.Compression.GZipStream]::new($CompressedFileStream, [System.IO.Compression.CompressionMode]::Decompress)
20+
$GZipStream.CopyTo($DecompressedFileStream)
21+
22+
# Cleanup
23+
$DecompressedFileStream.Dispose()
24+
$GZipStream.Dispose()
25+
$CompressedFileStream.Dispose()
26+
$DecompressedFileStream, $GZipStream, $CompressedFileStream = $null
27+
28+
# Remove the initial file if requested.
29+
if ($PSBoundParameters.ContainsKey('RemoveInputFile')) {
30+
$InputObject.Delete()
31+
}
32+
}
33+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function Get-UserAgentData {
2+
[CmdletBinding()]
3+
4+
$datPath = Join-Path -Path $PSScriptRoot -ChildPath "..\data\user-agents.dat"
5+
6+
if (-Not(Test-Path $datPath)) {
7+
Initialize-Dataset
8+
}
9+
10+
Import-Clixml -Path $datPath
11+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
function Initialize-Dataset {
2+
Process {
3+
4+
$gzPath = Join-Path -Path $PSScriptRoot -ChildPath "..\data\user-agents.json.gz"
5+
$jsonPath = Join-Path -Path $PSScriptRoot -ChildPath "..\data\user-agents.json"
6+
$dll = Join-Path -Path $PSScriptRoot -ChildPath "..\tools\UAParser.dll"
7+
8+
if (-Not(Test-Path $jsonPath)) {
9+
ConvertFrom-Gzip -InputObject (Get-Item -Path $gzPath)
10+
}
11+
12+
if (-Not(Test-Path $datPath)) {
13+
Add-Type -Path $dll
14+
$uaParser = [UAParser.Parser]::GetDefault()
15+
16+
17+
$jsonFile = (Get-Item -Path $jsonPath)
18+
$processed = $jsonFile | Get-Content -Raw | ConvertFrom-Json | % {
19+
$ua_result = $uaParser.Parse($_.userAgent)
20+
21+
[PSCustomObject]@{
22+
ua = $_.userAgent
23+
percent = [decimal]($_.weight * 100)
24+
type = $_.deviceCategory
25+
device_brand = $ua_result.Device.Brand
26+
browser = $ua_result.UserAgent.Family
27+
browser_version = [version]::new($ua_result.UserAgent.Major, $ua_result.UserAgent.Minor, $ua_result.UserAgent.Patch, $ua_result.UserAgent.PatchMinor)
28+
browser_version_major_minor = [version]::new($ua_result.UserAgent.Major, $ua_result.UserAgent.Minor)
29+
os = $ua_result.OS.Family
30+
os_version = [version]::new($ua_result.OS.Major, $ua_result.OS.Minor, $ua_result.OS.Patch, $ua_result.OS.PatchMinor)
31+
platform = $_.platform
32+
}
33+
}
34+
35+
$jsonFile | Remove-Item
36+
$processed | Export-Clixml -Path $datPath
37+
}
38+
}
39+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function Get-UserAgent {
2+
[CmdletBinding()]
3+
param ()
4+
5+
$data = Get-UserAgentData
6+
return $data
7+
8+
}
9+
10+
Export-ModuleMember -Function Get-UserAgent
203 KB
Binary file not shown.

Fake-UserAgent/tools/UAParser.dll

247 KB
Binary file not shown.

LICENSE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Alan Płócieniak
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6+
7+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8+
9+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Fake-UserAgent
2+
3+
PowerShell module for generating random **User Agents**.
4+
5+
6+
## How to use
7+
8+
```powershell
9+
$agents = Get-UserAgent
10+
```
11+
12+
Output
13+
14+
```text
15+
ua : Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Mobile/15E148 Safari/604.1
16+
percent : 0.0969801619581542
17+
type : mobile
18+
device_brand : Apple
19+
browser : Mobile Safari
20+
browser_version : 18.1.1.0
21+
browser_version_major_minor : 18.1
22+
os : iOS
23+
os_version : 18.1.1.0
24+
platform : iPhone
25+
```
26+
27+
## How it works
28+
29+
- module comes with `user-agents.json.gz` downloaded from [**user-agents**](https://github.com/intoli/user-agents/)
30+
- during first cmdlet call data will be unpacked and converted into **user-agents.dat** with help of [**uap-csharp**](https://github.com/ua-parser/uap-csharp/)
31+
32+
## Acknowledgements
33+
This project makes use of the following project
34+
- [**user-agents**](https://github.com/intoli/user-agents/) by [**intoli**](https://github.com/intoli)
35+
*A JavaScript library for generating random user agents with data that's updated daily.*
36+
- [**uap-csharp**](https://github.com/ua-parser/uap-csharp/) by [**ua-parser**](https://github.com/ua-parser)
37+
*C# implementation of ua-parser*
38+
39+
## License
40+
[MIT License](LICENSE.md) © Alan Płócieniak
41+
42+
43+

Tests/Toggl.API.Tests.ps1

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
Import-Module -Name Pester -Force
2+
Import-Module .\Fake-UserAgent\Fake-UserAgent.psm1 -Force
3+
4+
Describe 'Fake-UserAgent.Tests' {
5+
Context "Get-UserAgentData Tests" {
6+
7+
BeforeAll {
8+
$gzPath = '.\Fake-UserAgent\data\user-agents.json.gz'
9+
$jsonPath = '.\Fake-UserAgent\data\user-agents.json'
10+
$datPath = '.\Fake-UserAgent\data\user-agents.dat'
11+
12+
Remove-Item -Path $jsonPath -ErrorAction SilentlyContinue
13+
Remove-Item -Path $datPath -ErrorAction SilentlyContinue
14+
}
15+
16+
It "should have initial state" {
17+
Test-Path $gzPath | Should -Be $true
18+
Test-Path $jsonPath | Should -Be $false
19+
Test-Path $datPath | Should -Be $false
20+
}
21+
22+
It "should not throw exception during initialization" {
23+
{ Get-UserAgent } | Should -Not -Throw
24+
}
25+
26+
It "should have initialized state" {
27+
Test-Path $gzPath | Should -Be $true
28+
Test-Path $jsonPath | Should -Be $false
29+
Test-Path $datPath | Should -Be $true
30+
}
31+
32+
It "should have user agents" {
33+
$agents = Get-UserAgent
34+
$agents | Should -Not -BeNullOrEmpty
35+
$agents.Count | Should -BeGreaterThan 0
36+
}
37+
38+
It "should have correct structure" {
39+
$agent = Get-UserAgent | Select-Object -Skip 2 -First 1
40+
$agent.ua | Should -Be "Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Mobile/15E148 Safari/604.1"
41+
$agent.percent | Should -Be ([decimal]0.0969801619581542)
42+
$agent.type | Should -Be "mobile"
43+
$agent.device_brand | Should -Be "Apple"
44+
$agent.browser | Should -Be "Mobile Safari"
45+
$agent.browser_version | Should -Be ([version]::new(18, 1, 1, 0))
46+
$agent.browser_version_major_minor | Should -Be ([version]::new(18, 1))
47+
$agent.os | Should -Be "iOS"
48+
$agent.os_version | Should -Be ([version]::new(18, 1, 1, 0))
49+
$agent.platform | Should -Be "iPhone"
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)