Reputation: 595
I need to replace ip-netmask
with fqdn
if dns resolution is successful.
This script will be used to replace values in a config file.
If DNS is resolved, I need to change the property name of ip-netmask
to fqdn
and store the new dns value under it. The script resolves DNS and only updates ip-netmask if successful, and is also adding an fqdn property with the DNS value if successful.
Seems like I’m sort of there, but I am not able to rename ip-netmask to fqdn, or just delete the ip-netmask property without making my fqdn property null
From original json input
@'{
"entry":[
{
"@name":"31.170.162.203",
"ip-netmask":"31.170.162.203",
"description":"test1"
},
{
"@name":"37.193.217.222",
"ip-netmask":"37.193.217.222",
"description":"test2"
},
{
"@name":"46.17.63.169",
"ip-netmask":"46.17.63.169",
"description":"test3"
}
]
}
Here's my script
$a = Get-Content 'C:\Users\e\Desktop\puttytest1.json' | ConvertFrom-Json
$a.entry | ForEach-Object {
if ($namehost = (Resolve-DnsName $_.'ip-netmask').namehost) {
$_.'ip-netmask' = $namehost
$_ | Add-Member -MemberType AliasProperty -Name fqdn -Value ip-netmask
}
}
$newjson = $a | ConvertTo-Json
$newjson
And here's the output:
{
"entry": [
{
"@name": "31.170.165.68",
"ip-netmask": "31.170.165.68",
"description": "Test1"
},
{
"@name": "31.170.162.203",
"ip-netmask": "31.170.162.203",
"description": "test2"
},
{
"@name": "37.193.217.222",
"ip-netmask": "l37-193-217-222.novotelecom.ru",
"description": "test3",
"fqdn": "l37-193-217-222.novotelecom.ru"
}
]
}
Upvotes: 3
Views: 17271
Reputation: 21
I'm using :
function Rename-Properties(){
[CmdletBinding()]
Param([Parameter(ValueFromPipeline=$true,Mandatory=$true,Position=0)][Object]$inputObject
, [Parameter(ValueFromPipeline=$false,Mandatory=$false)][Object]$NewNames
, [Parameter(ValueFromPipeline=$false,Mandatory=$false)][switch]$Keep=$false
)
# Parameter NewNames: can take (a mapping) HashTable{Key(NewName)=Value(Name)]
# or object collection with properties Name,NewName
# e.g. $myInputObject.PSObject.properties | Where-Object {$_.Name -like '*'} | Select-Object Name,@{N='NewName';E={"Prefixed_$($_.Name"}}
if($NewNames -is [HashTable]) { $NewNames = $NewNames.GetEnumerator() | Select-Object @{N='Name';E={$_.Value}},@{N='NewName';E={$_.Key}} }
# ensure NewName exists and is unique
$NewNames = ( $NewNames | Where-Object {$_.NewName.length -gt 0} | Group-Object -Property NewName | ForEach-Object{$_.Group[0]} )
$props = @('*')
ForEach($prp in $NewNames) {
$props += @{N="$($prp.NewName)";E=([Scriptblock]::Create("`$_.$($prp.Name)"))}
}
if($Keep) {
return ($inputObject | Select-Object -Property $props )
} else {
return ($inputObject | Select-Object -Property $props -ExcludeProperty $NewNames.Name )
}
}
Upvotes: 1
Reputation: 178
There is actually a really simple way of doing this without the need of removing anything. I spent a lot of time troubleshooting my own issue so forgive me for not converting names into your context, but hope this helps. This is my first post to the community, so take it easy on me lol.
The starting properties of my PSCustomObject (same would apply to any object). The goal was to rename the property names and in my case retain a certain order.
$roleMappingsCSV | Get-Member -MemberType Properties | Select-Object Name, MemberType
Name MemberType
---- ----------
Identifiers NoteProperty
IdentifierType NoteProperty
InlinePolicy NoteProperty
ManagedPolicy NoteProperty
Members NoteProperty
Role NoteProperty
Solution
$roleMappingsCSV_Proper = $roleMappingsCSV | Select-Object @{N='IAM_Role'; E={$_.Role}},`
@{N='Basis_Type'; E={$_.IdentifierType}},`
@{N='Basis_for_Access'; E={$_.Identifiers}},`
@{N='Members'; E={$_.Members}},`
@{N='Managed_Policy'; E={$_.ManagedPolicy}},`
@{N='InlinePolicy'; E={$_.InlinePolicy}}
Now you can see that the PSCustomObject just gets stored into a new object with the custom renamed property fields.
$roleMappingsCSV_Proper | Get-Member -MemberType Properties | Select-Object Name, MemberType
Name MemberType
---- ----------
Basis_for_Access NoteProperty
Basis_Type NoteProperty
IAM_Role NoteProperty
InlinePolicy NoteProperty
Managed_Policy NoteProperty
Members NoteProperty
Upvotes: 1
Reputation: 61123
You shouldn't try to rename an existing property, but instead remove it and add the new NoteProperty to the object, like this:
$newjson = $a.entry | ForEach-Object {
if ($namehost = (Resolve-DnsName $_.'ip-netmask').namehost) {
# remove the 'ip-netmask' property
$_.PSObject.Properties.Remove('ip-netmask')
# add a new NoteProperty 'fqdn'
$_ | Add-Member -MemberType NoteProperty -Name 'fqdn' -Value $namehost
}
} | ConvertTo-Json
However, I believe you're using the wrong method for retrieving the fqdn from an IP address.. Shouldn't that be:
$newjson = $a.entry | ForEach-Object {
if ($namehost = [System.Net.Dns]::GetHostByAddress($($_.'ip-netmask')).HostName) {
# remove the 'ip-netmask' property
$_.PSObject.Properties.Remove('ip-netmask')
# add a new NoteProperty 'fqdn'
$_ | Add-Member -MemberType NoteProperty -Name 'fqdn' -Value $namehost
}
} | ConvertTo-Json
Hope that helps
To maintain that order, use
$newjson = $a.entry | ForEach-Object {
if ($namehost = (Resolve-DnsName $_.'ip-netmask').namehost) {
# output a new object with properties ordered like you want them to be
$_ | Select-Object '@name', @{Name = 'fqdn'; Expression = {$namehost}}, 'description'
}
else {
# output the object unchanged
$_
}
} | ConvertTo-Json
Upvotes: 5