powershelldns

Small section of code in my PS script returning an error


The code below is a section of a PS script I'm writing. Everything works except a small section that I copied as the script function is new for me. The section below is embedded in a menu.

The line "$whatIfResult = Invoke-Command -ScriptBlock {& $args[0] -WhatIf} -ArgumentList $command ", specifically "{& $args[0] -WhatIf}" is returning the error:

"*The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script block, or a CommandInfo object. At line:25 char:53

Full section is shown below.

     {
        $requiredColumns = "Zone","Computer","HostName","Name","TimeToLive"

        $csvPath = Read-Host "Enter full path to CSV file"

        $csv = Import-Csv $csvPath
            $missingColumns = $requiredColumns | Where-Object {$_ -notin $csv[0].PSObject.Properties.Name}

            if($missingColumns.Count -gt 0){
                Write-Output "The following required columns are missing from csv: $missingColumns"
            } else {
                Write-Output "All required columns are present in the csv file."
            }

        foreach ($record in $csv) {
            $zoneName = $record.Zone
            $computer = $record.Computer
            $NewHostName = $record.HostName
            $Name = $record.Name
            $ttl = $record.TimeToLive

        # Add the new PTR record with whatif and confirm changes
        $command = Add-DnsServerResourceRecordPtr -ComputerName $computer -ZoneName $zoneName -AllowUpdateAny -TimeToLive $ttl -AgeRecord -Name $Name -PtrDomainName $NewHostName

        # Run the command with -WhatIf
        $whatIfResult = Invoke-Command -ScriptBlock {& $args[0] -WhatIf} -ArgumentList $command

        # Prompt for confirmation
        if ($whatIfResult) {
            $confirmation = Read-Host -Prompt "Do you want to apply these changes? (y/n)"
                if ($confirmation -eq "y") {
                    # Execute the command without -WhatIf
                    Invoke-Expression $command
                    Write-Host "Changes applied."
                } else {
                    Write-Host "Changes not applied."
                }
            }
        }
        Write-Host "Option 1 selected"
    }

Any help would be greatly appreciated.


Solution

  • I think I see what you're trying to achieve there, but I think your problem is that the code doesn't do what you're perhaps expecting it to. The line :

    # Add the new PTR record with whatif and confirm changes
    $command = Add-DnsServerResourceRecordPtr -ComputerName $computer -ZoneName $zoneName -AllowUpdateAny -TimeToLive $ttl -AgeRecord -Name $Name -PtrDomainName $NewHostName
    

    doesn't assign that command to $command so it can be run later, it runs it immediately and assigns any output from that command to the variable.

    Your easiest option is to get rid of most of that chunk of code, and replace it with this simplified version :

    Add-DnsServerResourceRecordPtr -ComputerName $computer -ZoneName $zoneName -AllowUpdateAny -TimeToLive $ttl -AgeRecord -Name $Name -PtrDomainName $NewHostName -WhatIf
    $confirmation = Read-Host -Prompt "Do you want to apply these changes? (y/n)"
    if ($confirmation -eq "y") {
        # Execute the command without -WhatIf
        Add-DnsServerResourceRecordPtr -ComputerName $computer -ZoneName $zoneName -AllowUpdateAny -TimeToLive $ttl -AgeRecord -Name $Name -PtrDomainName $NewHostName
        Write-Host "Changes applied."
    } else {
        Write-Host "Changes not applied."
    }
    

    You obviously end up with the Add-DnsServerResourceRecordPtr line written out twice, but since you're programmatically generating all the parameters anyway I don't think it's the end of the world.

    Update - altered version showing all THEN seeking confirmation.

    foreach ($record in $csv) {
        $zoneName = $record.Zone
        $computer = $record.Computer
        $NewHostName = $record.HostName
        $Name = $record.Name
        $ttl = $record.TimeToLive
    
        # Show the whatif for each record
        Add-DnsServerResourceRecordPtr -ComputerName $computer -ZoneName $zoneName -AllowUpdateAny -TimeToLive $ttl -AgeRecord -Name $Name -PtrDomainName $NewHostName -WhatIf
    }
    # Prompt for confirmation
    $confirmation = Read-Host -Prompt "Do you want to apply these changes? (y/n)"
    if ($confirmation -eq "y") {
        # Execute the commands without -WhatIf
        foreach ($record in $csv) {
            $zoneName = $record.Zone
            $computer = $record.Computer
            $NewHostName = $record.HostName
            $Name = $record.Name
            $ttl = $record.TimeToLive
    
            Add-DnsServerResourceRecordPtr -ComputerName $computer -ZoneName $zoneName -AllowUpdateAny -TimeToLive $ttl -AgeRecord -Name $Name -PtrDomainName $NewHostName
        }
        Write-Host "Changes applied."
    } else {
        Write-Host "Changes not applied."
    }