NetworkProfile.psm1
#Region '.\Private\Convert-NetworkProfileTimestamp.ps1' -1 Function Convert-NetworkProfileTimestamp { <# .SYNOPSIS Convert binary time data from Network Profile registry keys to datetime object .DESCRIPTION Network Profiles are stored in the registry and two timestamp values stored in binary. This function will convert those timestamps to a datetime object. .PARAMETER RegTimeStamp The binary array representing a timestamp .EXAMPLE Convert-NetworkProfileTimestamp -RegTimeStamp $Profile.GetValue("DateCreated") #> Param ( [Byte[]]$RegTimeStamp ) $First = 1 $Second = 0 $Values = while ($First -lt 15) { if ($First -eq 5) { #the bytes in the 4th and 5th are the day of the week which we don't need } else { [uint32]$('0x{0:x}{1:x}' -f $RegTimeStamp[$First], $RegTimeStamp[$Second]) } $First+=2 $Second+=2 } New-Object Datetime ($Values) } #EndRegion '.\Private\Convert-NetworkProfileTimestamp.ps1' 29 #Region '.\Public\Get-NetworkProfile.ps1' -1 Function Get-NetworkProfile { <# .SYNOPSIS Function to return network profiles from registry as Powershell objects .DESCRIPTION Query the Local Machine registry hive for current network profiles and return them as Powershell objects. Requires administrative privilege to read the hive. .PARAMETER ProfileName Return a specific network profile by name. Uses regex for matching. .PARAMETER GUID Return a specific network profile by GUID. If you run Get-NetworkProfile with no arguments, the returned objects have a property called 'GUID' that's not shown in the table format view. Either pipe the output to `select *` or `format-list` to view the GUIDs. Can also be seen if capturing the output in a variable and then calling the property. .EXAMPLE PS> Get-NetworkProfile ProfileName Description Managed Category DateCreated NameType DateLastConnected ----------- ----------- ------- -------- ----------- -------- ----------------- PSHSummit PSHSummit No Public 4/8/2024 8:58:09 AM Wireless Network 4/10/2024 12:58:16 PM Gizmo Network No Public 7/16/2024 3:23:27 PM Wireless Network 7/16/2024 4:09:02 PM contoso contoso.lcl Yes Domain 1/31/2024 5:28:46 PM Wired Network 7/16/2024 3:25:07 PM # with no arguments it returns all network profiles found in the registry .EXAMPLE PS> $Profile = Get-NetworkProfile -ProfileName PSHSummit PS> $Profile | Format-List ProfileName : PSHSummit Description : PSHSummit Managed : No Category : Public DateCreated : 4/8/2024 8:58:09 AM NameType : Wireless Network DateLastConnected : 4/10/2024 12:58:16 PM GUID : 4b2c4e83-90ca-4aa4-a321-2a7b08d3d669 # now with the GUID property we can use it to retrieve that specific profile. PS> Get-NetworkProfile -GUID 4b2c4e83-90ca-4aa4-a321-2a7b08d3d669 ProfileName Description Managed Category DateCreated NameType DateLastConnected ----------- ----------- ------- -------- ----------- -------- ----------------- PSHSummit PSHSummit No Public 4/8/2024 8:58:09 AM Wireless Network 4/10/2024 12:58:16 PM #> #Requires -RunAsAdministrator [CmdletBinding(DefaultParameterSetName="none")] Param ( [Parameter(Mandatory=$false,Position=0,ParameterSetName="ProfileName")] [Alias("Name")] [Regex]$ProfileName, [Parameter(Mandatory=$false,Position=1,ParameterSetName="GUID")] [Guid]$GUID ) $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles" $RegProfiles = switch ($PSCmdlet.ParameterSetName) { "ProfileName" { try { Get-ChildItem $RegPath -ErrorAction Stop | Where-Object { $_.GetValue("ProfileName") -match $ProfileName.ToString() } } catch { throw $Error[0] } } "GUID" { try { $ProfilePath = Join-Path -Path $RegPath -ChildPath "{$($GUID.ToString())}" if (Test-Path $ProfilePath) { Get-Item -Path $ProfilePath } else { Write-Warning "No network profile found matching GUID: {$($GUID.ToString())}" } } catch { throw $Error[0] } } "none" { try { Get-ChildItem $RegPath -ErrorAction Stop } catch { throw $Error[0] } } } Foreach ($Profile in $RegProfiles) { $Managed = Get-ItemPropertyValue -Path $(Join-Path -Path $RegPath -ChildPath $Profile.PSChildName) -Name "Managed" | Foreach-Object { if ($_ -eq 1) { "Yes" } else { "No" } } $Category = Get-ItemPropertyValue -Path $(Join-Path -Path $RegPath -ChildPath $Profile.PSChildName) -Name "Category" | Foreach-Object { switch ($_) { 0 {"Public"} 1 {"Private"} 2 {"Domain"} } } $DateCreated = Convert-NetworkProfileTimestamp -RegTimeStamp $Profile.GetValue("DateCreated") $NameTypeValue = Get-ItemPropertyValue -Path $(Join-Path -Path $RegPath -ChildPath $Profile.PSChildName) -Name "NameType" | Foreach-Object { switch ($_) { 6 {"Wired Network"} 23 {"VPN"} 53 {"VPN"} 71 {"Wireless Network"} 243 {"Mobile Broadband"} } } $DateLastConnected = Convert-NetworkProfileTimestamp -RegTimeStamp $Profile.GetValue("DateLastConnected") [PSCustomObject]@{ PSTypeName = "NetworkProfile" ProfileName = $Profile.GetValue("ProfileName") Description = $Profile.GetValue("Description") Managed = $Managed Category = $Category DateCreated = $DateCreated NameType = $NameTypeValue DateLastConnected = $DateLastConnected GUID = [GUID]$Profile.PSChildName } } } #EndRegion '.\Public\Get-NetworkProfile.ps1' 124 #Region '.\Public\Remove-NetworkProfile.ps1' -1 Function Remove-NetworkProfile { <# .SYNOPSIS Function to change the name, description or category of existing network profiles in registry .DESCRIPTION Function takes the unique ProfileName, GUID, or pipeline input of an existing network profile from registry and allows for updating the description, name and/or category of that profile. .PARAMETER ProfileName ProfileName to target for updating. Accepts pipeline input. .PARAMETER GUID Specify the GUID without braces for the network profile. Accepts pipeline input from Get-NetworkProfile .EXAMPLE PS> Get-networkprofile -ProfileName PSHSummit | Remove-NetworkProfile Confirm Are you sure you want to perform this action? Performing the operation "Remove-Item" on target "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\{4b2c4e83-90ca-4aa4-a321-2a7b08d3d669}". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): y #> #Requires -RunAsAdministrator [CmdletBinding(DefaultParameterSetName="ProfileName",SupportsShouldProcess,ConfirmImpact="High")] Param ( [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="ProfileName")] [Alias("Name")] [Regex]$ProfileName, [Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="GUID")] [guid]$GUID ) begin { $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles" } process { switch ($PSBoundParameters.Keys) { "GUID" { $ProfilePath = Join-Path -Path $RegPath -ChildPath "{$($GUID.ToString())}" if (Test-Path $ProfilePath) { $NetworkProfile = Get-NetworkProfile -GUID $GUID } else { Write-Warning "No network profile with GUID $GUID found" } } "ProfileName" { $NetworkProfile = Get-NetworkProfile -ProfileName $ProfileName $ProfilePath = Join-Path -Path $RegPath -ChildPath "{$($NetworkProfile.GUID)}" if ($NetworkProfile.count -gt 1) { Write-Warning "Multiple network profiles match the name $ProfileName . Please use the -GUID parameter to specify a single network profile or find a more specific name." $NetworkProfile = $null } elseif ($null -eq $NetworkProfile) { Write-Warning "No network profile with name $ProfileName found" } } } if ($NetworkProfile) { Write-Verbose "Removing network profile: $($NetworkProfile.ProfileName) / $($NetworkProfile.GUID.ToString())" if ($PSCmdlet.ShouldProcess($ProfilePath,'Remove-Item')) { try { Remove-Item -Path $ProfilePath } catch { $Error[0] } } } } end {} } #EndRegion '.\Public\Remove-NetworkProfile.ps1' 69 #Region '.\Public\Set-NetworkProfile.ps1' -1 Function Set-NetworkProfile { <# .SYNOPSIS Function to change the name, description or category of existing network profiles in registry .DESCRIPTION Function takes the unique ProfileName, GUID, or pipeline input of an existing network profile from registry and allows for updating the description, name and/or category of that profile. .PARAMETER ProfileName ProfileName to target for updating. Accepts pipeline input. .PARAMETER GUID Specify the GUID without braces for the network profile. Accepts pipeline input from Get-NetworkProfile .PARAMETER NewProfileName Specify the new profile name to change the network profile to .PARAMETER Description Change the description text for the network profile .PARAMETER Category Change the category for the network profile. Options are Private, Public or Domain .EXAMPLE PS$> Get-NetworkProfile -ProfileName PSHSummit ProfileName Description Managed Category DateCreated NameType DateLastConnected ----------- ----------- ------- -------- ----------- -------- ----------------- PSHSummit PSHSummit No Public 4/8/2024 8:58:09 AM Wireless Network 4/10/2024 12:58:16 PM PS$> Get-NetworkProfile -ProfileName PSHSummit | Set-NetworkProfile -Description "Powershell Rocks" -Category "Private" PS$> Get-NetworkProfile -ProfileName PSHSummit ProfileName Description Managed Category DateCreated NameType DateLastConnected ----------- ----------- ------- -------- ----------- -------- ----------------- PSHSummit Powershell Rocks No Private 4/8/2024 8:58:09 AM Wireless Network 4/10/2024 12:58:16 PM #> #Requires -RunAsAdministrator [CmdletBinding(DefaultParameterSetName="ProfileName")] Param ( [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="ProfileName")] [Alias("Name")] [Regex]$ProfileName, [Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="GUID")] [guid]$GUID, [Parameter(ParameterSetName="ProfileName")] [Parameter(ParameterSetName="GUID")] [String]$NewProfileName, [Parameter(ParameterSetName="ProfileName")] [Parameter(ParameterSetName="GUID")] [String]$Description, [Parameter(ParameterSetName="ProfileName")] [Parameter(ParameterSetName="GUID")] [ValidateSet("Private","Public","Domain")] [String]$Category ) begin { $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles" } process { switch ($PSBoundParameters.Keys) { "GUID" { $ProfilePath = Join-Path -Path $RegPath -ChildPath "{$($GUID.ToString())}" if (Test-Path $ProfilePath) { $NetworkProfile = Get-NetworkProfile -GUID $GUID } else { Write-Warning "No network profile with GUID $GUID found" } } "ProfileName" { $NetworkProfile = Get-NetworkProfile -ProfileName $ProfileName $ProfilePath = Join-Path -Path $RegPath -ChildPath "{$($NetworkProfile.GUID)}" if ($NetworkProfile.count -gt 1) { Write-Warning "Multiple network profiles match the name $ProfileName . Please use the -GUID parameter to specify a single network profile or find a more specific name." $NetworkProfile = $null } elseif ($null -eq $NetworkProfile) { Write-Warning "No network profile with name $ProfileName found" } } } if ($NetworkProfile) { Write-Verbose "Updating properties on ProfileName: $($NetworkProfile.ProfileName)" $ValuesToSet = switch ($PSBoundParameters.Keys) { "NewProfileName" { [PSCustomObject]@{ Name = "ProfileName" Value = $NewProfileName } } "Description" { [PSCustomObject]@{ Name = "Description" Value = $Description } } "Category" { [PSCustomObject]@{ Name = "Category" Value = switch ($Category) { "Public" {0} "Private" {1} "Domain" {2} } } } } try { $ValuesToSet | Set-ItemProperty -Path $ProfilePath -Name {$_.Name} -ErrorAction Stop } catch { throw $Error[0] } } } end {} } #EndRegion '.\Public\Set-NetworkProfile.ps1' 114 |