使用 powershell 根据计算机所在的 IP 范围或 pc 主机名的前 3 个字符设置环境变量 (LOCID)
Use powershell to set an environment variable (LOCID) based on what IP range the computer is in or the first 3 characters of the pc hostname
我一直在使用 cmd/batch 文件根据计算机所在的 IP 范围创建 locationid 变量。我需要使用 powershell 执行类似的功能。欢迎任何建议。
作为我在批处理文件中使用的代码示例:
For /F "Delims==" %%G In ('Set octet 2^>NUL')Do Set "%%G="
For /F "Tokens=2 Delims=:" %%G In (
'"%__AppDir__%ipconfig.exe 2>NUL|%__Appdir__%find.exe "IPv4""'
)Do For /F "Tokens=1-4Delims=. " %%H In ("%%G"
)Do Set "octet1=%%H"&Set "octet2=%%I"&Set "octet3=%%J"&Set "octet4=%%K"
Set octet>NUL 2>&1||(Echo IPConfig failed to retrieve an IP address.
Pause&GoTo :EOF)
Set "BuildingLOC="
If %octet1% Equ 10 If Defined octet2 (
If %octet2% GEq 6 If %octet2% LEq 7 Set "BuildingLOC=VM"
If %octet2% GEq 10 If %octet2% LEq 19 Set "BuildingLOC=ADM"
)
使用 IP 八位字节:
function Get-HostIP {
[CmdletBinding()]
[OutputType([string])]
param ()
#
$Return = (
Get-NetIPConfiguration | Where-Object {
$null -ne $_.IPv4DefaultGateway -and $_.NetAdapter.Status -ne "Disconnected"
}
).IPv4Address.IPAddress
return $Return
}
Function Get-IPOctets {
[CmdletBinding()]
[OutputType([int[]])]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$IPAddress
)
if( $IPAddress -match '(?<Octet1>\d+)\.(?<Octet2>\d+)\.(?<Octet3>\d+)\.(?<Octet4>\d+)') {
return $Matches.Octet1, $Matches.Octet2, $Matches.Octet3, $Matches.Octet4
} else {
return 0, 0, 0, 0
}
}
$Octet1, $Octet2, $Octet3, $Octet4 = Get-IPOctets (Get-HostIP)
if($Octet1 -eq 10) {
switch ($Octet2) {
{$_ -in 6..7} {$BuildingLOC = 'VM'; break}
{$_ -in 10..19} {$BuildingLOC = 'ADM'; break}
default {$BuildingLOC = 'Other'; break}
}
} else {
$BuildingLOC = 'Invalid'
}
Write-Host "IPType: $BuildingLOC"
使用计算机名称的前 3 个字母:
if($HostName = [System.Net.Dns]::GetHostName()) {
if($HostName.Substring(0, 3) -eq 'ABC') {
Write-Host "Computer name matches"
} else {
Write-Host "Computer name does not match "
}
} else {
Write-Host "No computer name"
}
编辑:
最初错过了评论中关于setx /m的问题,所以这里有几个与环境变量相关的选项。
SetEnvironmentVariable/GetEnvironmentVariable:
看看. Note that 'Path' is the variable name in the examples, but use any name you desire. For the SetEnvironmentVariable $Value is the value being saved. And also note that there are 3 places, Process/Machine/User, in the GetEnvironmentVariable examples, which is where the variable is stored or retrieved from. I like these example because the full reference to target locations is given, but if you look through examples in 中的例子,可以看到可以简写为'Process'、'Machine'、'User'.
- Process: 我相信这只是临时存储,与使用 $Env:MyVar 相同。 GetEnvironmentVariable 可以读取当前会话内存中的任何内容,但只要当前 PowerShell 会话关闭,SetEnvironmentVariable 设置的任何内容都会丢失。
- 机器:所有用户都可以使用这些变量,并且即使在重新启动后仍然可用。但可能无法通过当前脚本会话中的 $Env:MyVar 获得。
- 用户:仅对当前用户可用,即使重启后也将保持可用。但可能无法通过当前脚本会话中的 $Env:MyVar 获得。
setx.exe:
任何可执行文件都可以来自 PowerShell 运行,但有几点需要注意。如果你翻看我前几天给的this answer你可以看到:
- 您可以下载 EchoArgs from ss64.com,执行 EchoArgs 而不是您的 exe 文件,在本例中为 setx,记录传递给 EchoArgs 的参数的模式,然后在 PowerShell 中构建输出完全相同参数的 EchoArgs 行模式,最后用您的 exe 文件替换 PowerShell EchoArgs,在本例中为 setx。
- 在问题的更下方,我介绍了 --% parameter/operator 的使用,它会导致 PowerShell 停止处理该行并按原样传递它。
- 然后我将解释如何使用环境变量动态替换 --% parameter/operator.
之后的部分行
在同一个问题中可以找到一个更短但相似的答案 . BUT, if you look ,你可以看到他使用 Start-Process -FilePath $RunPath -ArgumentList $MyArgsText
启动 exe 文件并向其传递参数。我还没有花时间去试验 Start-Process,但它看起来是一个有趣的选择。
REG.EXE:
您可以使用的另一个 exe 文件是 REG.EXE。如果您查看 this page,您会看到描述的机器、进程和用户,其中包括存储环境变量的注册表项。我实际上很久以前就停止在批处理文件中使用 setx,因为我 运行 进入 setx 无法存储的值,但 REG.EXE 没有问题。
以下是我在一些批处理文件中找到的一些示例:
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "EnableUAC" /T "REG_SZ" /D "Yes" /F>NUL 2>&1
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "%%A" /T REG_EXPAND_SZ /D "%~2" /F
REG DELETE "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "TemporaryMachineName" /F>NUL 2>&1
还有一个来自 PowerShell 脚本:
REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "PSModuleTest" 2>$null
PowerShell 注册表:
我不打算通过 PowerShell 编辑注册表,但请注意 Get-ItemPropertyValue/Set-ItemPropertyValue、Get-ItemProperty/Set-ItemProperty、Get-ChildItem/Set-ChildItem 和 Get-Item/Set-Item 很常见built-in 执行此操作的 PowerShell 命令。
要获得更多控制权并让您付出更多努力,您可以使用以下命令系列:[RegistryKey]::OpenRemoteBaseKey、[RegistryKey]::OpenBaseKey、$BaseKey.OpenSubKey、$SubKey.SetValue、$SubKey.GetValue、$SubKey.DeleteValue 和许多其他人。
我一直在使用 cmd/batch 文件根据计算机所在的 IP 范围创建 locationid 变量。我需要使用 powershell 执行类似的功能。欢迎任何建议。
作为我在批处理文件中使用的代码示例:
For /F "Delims==" %%G In ('Set octet 2^>NUL')Do Set "%%G="
For /F "Tokens=2 Delims=:" %%G In (
'"%__AppDir__%ipconfig.exe 2>NUL|%__Appdir__%find.exe "IPv4""'
)Do For /F "Tokens=1-4Delims=. " %%H In ("%%G"
)Do Set "octet1=%%H"&Set "octet2=%%I"&Set "octet3=%%J"&Set "octet4=%%K"
Set octet>NUL 2>&1||(Echo IPConfig failed to retrieve an IP address.
Pause&GoTo :EOF)
Set "BuildingLOC="
If %octet1% Equ 10 If Defined octet2 (
If %octet2% GEq 6 If %octet2% LEq 7 Set "BuildingLOC=VM"
If %octet2% GEq 10 If %octet2% LEq 19 Set "BuildingLOC=ADM"
)
使用 IP 八位字节:
function Get-HostIP {
[CmdletBinding()]
[OutputType([string])]
param ()
#
$Return = (
Get-NetIPConfiguration | Where-Object {
$null -ne $_.IPv4DefaultGateway -and $_.NetAdapter.Status -ne "Disconnected"
}
).IPv4Address.IPAddress
return $Return
}
Function Get-IPOctets {
[CmdletBinding()]
[OutputType([int[]])]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$IPAddress
)
if( $IPAddress -match '(?<Octet1>\d+)\.(?<Octet2>\d+)\.(?<Octet3>\d+)\.(?<Octet4>\d+)') {
return $Matches.Octet1, $Matches.Octet2, $Matches.Octet3, $Matches.Octet4
} else {
return 0, 0, 0, 0
}
}
$Octet1, $Octet2, $Octet3, $Octet4 = Get-IPOctets (Get-HostIP)
if($Octet1 -eq 10) {
switch ($Octet2) {
{$_ -in 6..7} {$BuildingLOC = 'VM'; break}
{$_ -in 10..19} {$BuildingLOC = 'ADM'; break}
default {$BuildingLOC = 'Other'; break}
}
} else {
$BuildingLOC = 'Invalid'
}
Write-Host "IPType: $BuildingLOC"
使用计算机名称的前 3 个字母:
if($HostName = [System.Net.Dns]::GetHostName()) {
if($HostName.Substring(0, 3) -eq 'ABC') {
Write-Host "Computer name matches"
} else {
Write-Host "Computer name does not match "
}
} else {
Write-Host "No computer name"
}
编辑:
最初错过了评论中关于setx /m的问题,所以这里有几个与环境变量相关的选项。
SetEnvironmentVariable/GetEnvironmentVariable:
看看
- Process: 我相信这只是临时存储,与使用 $Env:MyVar 相同。 GetEnvironmentVariable 可以读取当前会话内存中的任何内容,但只要当前 PowerShell 会话关闭,SetEnvironmentVariable 设置的任何内容都会丢失。
- 机器:所有用户都可以使用这些变量,并且即使在重新启动后仍然可用。但可能无法通过当前脚本会话中的 $Env:MyVar 获得。
- 用户:仅对当前用户可用,即使重启后也将保持可用。但可能无法通过当前脚本会话中的 $Env:MyVar 获得。
setx.exe:
任何可执行文件都可以来自 PowerShell 运行,但有几点需要注意。如果你翻看我前几天给的this answer你可以看到:
- 您可以下载 EchoArgs from ss64.com,执行 EchoArgs 而不是您的 exe 文件,在本例中为 setx,记录传递给 EchoArgs 的参数的模式,然后在 PowerShell 中构建输出完全相同参数的 EchoArgs 行模式,最后用您的 exe 文件替换 PowerShell EchoArgs,在本例中为 setx。
- 在问题的更下方,我介绍了 --% parameter/operator 的使用,它会导致 PowerShell 停止处理该行并按原样传递它。
- 然后我将解释如何使用环境变量动态替换 --% parameter/operator. 之后的部分行
在同一个问题中可以找到一个更短但相似的答案 Start-Process -FilePath $RunPath -ArgumentList $MyArgsText
启动 exe 文件并向其传递参数。我还没有花时间去试验 Start-Process,但它看起来是一个有趣的选择。
REG.EXE:
您可以使用的另一个 exe 文件是 REG.EXE。如果您查看 this page,您会看到描述的机器、进程和用户,其中包括存储环境变量的注册表项。我实际上很久以前就停止在批处理文件中使用 setx,因为我 运行 进入 setx 无法存储的值,但 REG.EXE 没有问题。
以下是我在一些批处理文件中找到的一些示例:
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "EnableUAC" /T "REG_SZ" /D "Yes" /F>NUL 2>&1
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "%%A" /T REG_EXPAND_SZ /D "%~2" /F
REG DELETE "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "TemporaryMachineName" /F>NUL 2>&1
还有一个来自 PowerShell 脚本:
REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V "PSModuleTest" 2>$null
PowerShell 注册表:
我不打算通过 PowerShell 编辑注册表,但请注意 Get-ItemPropertyValue/Set-ItemPropertyValue、Get-ItemProperty/Set-ItemProperty、Get-ChildItem/Set-ChildItem 和 Get-Item/Set-Item 很常见built-in 执行此操作的 PowerShell 命令。
要获得更多控制权并让您付出更多努力,您可以使用以下命令系列:[RegistryKey]::OpenRemoteBaseKey、[RegistryKey]::OpenBaseKey、$BaseKey.OpenSubKey、$SubKey.SetValue、$SubKey.GetValue、$SubKey.DeleteValue 和许多其他人。