CPR.psm1
# Public Function Example - Replace With Your Function function Add-YourFirstFunction { [CmdletBinding()] Param ( # Your parameters go here... ) # Your function code goes here... Write-Output "Your first function ran!" } enum Gender { Male = 1 Female = 0 } function Get-CPR { param ( [Parameter(Mandatory=$false)] [int]$age, [Parameter(Mandatory=$false)] [Gender]$gender, [switch]$useModuloValidation, [switch]$omitHyphen ) # If no age is specified - get a random age: if(!$age){ $age = Get-Random -Minimum 0 -Maximum 100 } # Calculate a starting date by subtracting "age" years from the current date $currentDate = Get-Date $birthDate = $currentDate.AddYears(-$age) # Subtract a random number of days (0-364) from the birth date $randomDays = Get-Random -Minimum 0 -Maximum 365 $randomDate = $birthDate.AddDays(-$randomDays) # Format the date part of the CPR number $datePart = $randomDate.ToString("ddMMyy") if ($gender){ $parity = $gender.value__ } else { $parity = Get-Random -Minimum 0 -Maximum 2 } $controlSequence = Get-Random -Minimum 1000 -Maximum 9999 if ($controlSequence % 2 -ne $parity){ $controlSequence++ } $cpr = $datePart + $controlSequence.ToString("D4") # Adjust the control sequence until the CPR number passes the modulo 11 check if ($useModuloValidation) { while (!(Test-CPR -cpr $cpr)) { $controlSequence += 2 if ($controlSequence -gt 9999) { $controlSequence = $controlSequence - 10000; } $cpr = $datePart + $controlSequence.ToString("D4") } } # Format the CPR number with or without a hyphen if ($omitHyphen) { $cpr = $datePart + $controlSequence.ToString("D4") } else { $cpr = $datePart.Insert(6, '-') + $controlSequence.ToString("D4") } return $cpr } function Get-CPRInfo { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string]$cpr ) process{ # Remove hyphen if present $cpr = $cpr -replace '-', '' # Extract date and control sequence parts $datePart = $cpr.Substring(0, 6) $controlSequence = $cpr.Substring(6) # Parse date part to a DateTime object $birthday = [DateTime]::ParseExact($datePart, "ddMMyy", $null) $currentDate = Get-Date if ($birthday -gt $currentDate){ $birthday = $birthday.AddYears(-100) } # Calculate age $age = $currentDate.Year - $birthday.Year if ($currentDate.DayOfYear -lt $birthday.DayOfYear) { $age-- } # Determine gender based on the last digit of the control sequence $gender = if ([int]$controlSequence[-1] % 2 -eq 0) { 'Female' } else { 'Male' } # Check if the CPR number is valid $valid = Test-CPR -cpr $cpr # Create and return a custom object with the requested properties $output = New-Object PSObject $output | Add-Member -Type NoteProperty -Name CPR -Value ($cpr.Insert(6, '-')) $output | Add-Member -Type NoteProperty -Name Valid -Value $valid $output | Add-Member -Type NoteProperty -Name Birthday -Value $birthday $output | Add-Member -Type NoteProperty -Name Age -Value $age $output | Add-Member -Type NoteProperty -Name Gender -Value $gender $output | Add-Member -Type NoteProperty -Name Control -Value $controlSequence return $output } } function Test-CPR { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string]$cpr ) process{ # Remove hyphen if present $cpr = $cpr -replace '-', '' if ($cpr.Length -ne 10) { Write-Output "Invalid CPR number. It should be a 10-digit number." return $false } # Extract date parts $day = [int]$cpr.Substring(0, 2) $month = [int]$cpr.Substring(2, 2) $year = [int]$cpr.Substring(4, 2) # Figure out century: if ($year -le [DateTime]::Now.Year - 2000) { $fullyear = 2000 + $year } else { $fullyear = 1900 + $year } # Check for valid date $isoDate = "$fullyear-$month-$day" If (-not (Test-Date $isoDate)){ Write-Output "Invalid date in CPR number." return $false } $weights = @(4, 3, 2, 7, 6, 5, 4, 3, 2, 1) $sum = 0 for ($i = 0; $i -lt $cpr.Length; $i++) { $digit = [int]::Parse($cpr[$i]) $sum += $digit * $weights[$i] } return ($sum % 11 -eq 0) } } Export-ModuleMember -Function Add-YourFirstFunction, Get-CPR, Get-CPRInfo, Test-CPR |