Powershell v2.0 Foreach loop failing when run on PS v4 - powershell

Hi is there a difference in the way that PS v4 (running from a 2012 server) reacts to a Foreach loop written in V2?
I have this simple script that works in v2 but produces an error on v4:
$Serverlist = Import-CSV "D:\PendingReboot\AllADServers.csv"
Foreach ($Computer.Name in $Serverlist)
{
$ADComputer = $Computer.Name
$ADOwner = $Computer.Description
If (!($Computer.Description))
{$ADOwner = "Unassigned"}
$ADOU = $AD | select DistinguishedName
"$ADComputer $ADOwner"
}
Server1 Team1
Server2 Team2
etc. etc.
The Error in V4 is:
At D:\PendingReboot\Test.ps1:2 char:23
+ Foreach ($Computer.Name in $Serverlist)
+ ~
Missing 'in' after variable in foreach loop.
At D:\PendingReboot\Test.ps1:2 char:43
+ Foreach ($Computer.Name in $Serverlist)
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingInInForeach

PetSerAl's comment is correct. You should be using foreach ($Computer in $ServerList). As for why it works in PowerShell v2 and not in v4, well I can only assume that they corrected the behavior, as it should have failed in v2.
Basically your .Name in that portion is doing nothing, as evidenced by the fact that you still needed to specify .Name on the very first line within the loop.
Essentially, this was a syntax error that wasn't caught in an earlier version.

Related

Setup deployment group agent with powershell failed

I try to run the script provided in “deployment group” section on my Win7 VM (what I do is just “copy\paste\run”).
$ErrorActionPreference="Stop";
If(-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole( [Security.Principal.WindowsBuiltInRole] “Administrator”)){ throw "Run command in an administrator PowerShell prompt"};
If($PSVersionTable.PSVersion -lt (New-Object System.Version("3.0"))){ throw "The minimum version of Windows PowerShell that is required by the script (3.0) does not match the currently running version of Windows PowerShell." };
If(-NOT (Test-Path $env:SystemDrive\'azagent')){mkdir $env:SystemDrive\'azagent'};
cd $env:SystemDrive\'azagent';
for($i=1; $i -lt 100; $i++){$destFolder="A"+$i.ToString();
if(-NOT (Test-Path ($destFolder))){mkdir $destFolder;cd $destFolder;break;}};
$agentZip="$PWD\agent.zip";
$DefaultProxy=[System.Net.WebRequest]::DefaultWebProxy;$securityProtocol=#();$securityProtocol+=[Net.ServicePointManager]::SecurityProtocol;
$securityProtocol+=[Net.SecurityProtocolType]::Tls12;[Net.ServicePointManager]::SecurityProtocol=$securityProtocol;
$WebClient=New-Object Net.WebClient;
$Uri='https://vstsagentpackage.azureedge.net/agent/2.204.0/vsts-agent-win-x64-2.204.0.zip';
if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))){$WebClient.Proxy= New-Object Net.WebProxy($DefaultProxy.GetProxy($Uri).OriginalString, $True);};
$WebClient.DownloadFile($Uri, $agentZip);
Add-Type -AssemblyName System.IO.Compression.FileSystem;
[System.IO.Compression.ZipFile]::ExtractToDirectory( $agentZip, "$PWD");
.\config.cmd --deploymentgroup --deploymentgroupname "MY_GROUP_NAME" --agent $env:COMPUTERNAME --runasservice --work '_work' --url 'https://dev.azure.com/MY_ORG_NAME/' --projectname 'MY_PROJ_NAME';
Remove-Item $agentZip;
And error occurs:
em $agentZip;
At line:1 char:179
+ ... Current() ).IsInRole( [Security.Principal.WindowsBuiltInRole] “Adminis ...
+ ~
Missing ')' in method call.
At line:1 char:180
+ ... nRole( [Security.Principal.WindowsBuiltInRole] “Administrator?){ throw ...
+ ~~~~~~~~~~~~~~
Unexpected token '“Administrator?' in expression or statement.
At line:1 char:180
+ ... nRole( [Security.Principal.WindowsBuiltInRole] “Administrator?){ throw ...
+ ~~~~~~~~~~~~~~
Missing closing ')' after expression in 'If' statement.
At line:1 char:194
+ ... Role( [Security.Principal.WindowsBuiltInRole] “Administrator?){ throw ...
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
Here is the info of powershell version:
Any suggestion is appreciated.
As mentioned in the question comments, the issue stems around faulty quotation marks in the provided registration script.
It seems to only affect more modern Windows/PowerShell versions, so it hasn't been addressed by Microsoft with any priority yet. For now, the workaround is to find and replace.
If you paste the script into a text editor, search for “Administrator” and replace with "Administrator".
If you paste the script into (a modern) PowerShell prompt directly, the faulty characters will be stripped and you will need to manually add them:

Update AddresBookPolicy AddressLists based on variable input

I am trying to update an Address Book Policy on Exchange Online.
Idea is that I parse some Address Lists and save these into a variable.
These could be passed into the Set-AddresBookPolicy.
So I start off with parsing these adresses:
$AddressLists = (Get-AddressList).Id | ? {$_ -like "*Company_1*"}
This results an array like \Company_1_Users, \Company_1_Contacts, \Company_1_DLs as expected.
I apply these with
Set-AddressBookPolicy -Identity "Company1" -AddressLists $AddressLists `
-RoomList "C1_Rooms" -GlobalAddressList "C1_GAL" -OfflineAddressBook "C1_OAB"
Result is an error:
WARNING: An unexpected error has occurred and a Watson dump is being generated: The operation can't be performed on this object because its status isn't valid.
The operation can't be performed on this object because its status isn't valid.
+ CategoryInfo : NotSpecified: (:) [Set-AddressBookPolicy], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.Exchange.Management.SystemConfigurationTasks.SetAddressBookPolicy
+ PSComputerName : outlook.office365.com
I've tried converting it to a string (with -join ',') and have tried casting it, but I can't get further then an error (which then is of another kind).
If I copy the output and then type it into the command, it works. So that part is correct. However, I would like to automate this.
Does anyone know how I can correctly provide an input into the below cmdlet and have it running as expected?
EDIT: added full script below:
$AddressLists = #()
$AddressLists = (Get-AddressList).Id | ? {$_ -like "*Company_1*"}
$AddressLists = $AddressLists -join ',' #Adding this line just results in another error...
Set-AddressBookPolicy -Identity "Company1" -AddressLists $AddressLists `
-RoomList "C1_Rooms" -GlobalAddressList "C1_GAL" -OfflineAddressBook "C1_OAB"
The result of $AddressLists is an array (System.Array) with contents:
\Company_1
\Company_1Country1
\Company_1Country2
\Company_1Department1
\Company_1Department2
If your variable produces what you are saying...
$AddressLists = (Get-AddressList).Id | {$_ -like "*Company_1*"}
\Company_1_Users,
\Company_1_Contacts,
\Company_1_DLs
Then In Theory When You Add It Into a ForEach Loop It Should Work Accordingly. I Don't Have Exchange To Test It (by removing $updatecommand and leaving the execution command :o)
Change the settings of an address book policy in Exchange Online
<https://learn.microsoft.com/en-us/exchange/address-books/address-book-policies/change-the-settings-of-an-address-book-policy>
$AddressLists = ("\Company_1_Users", "\Company_1_Contacts", "\Company_1_DLs")
$iD = "Company1"
$rL = "C1_Rooms"
$gAL = "C1_GAL"
$oAB = "C1_OAB"
ForEach($AddressList in $AddressLists){
Write-Host "Without an Exchange Server, I'm Just Demonstating The Update Process"
Write-Host "The AddressList Being Updated Is -- $AddressList"
$updatecommand = "Set-AddressBookPolicy -Identity $iD -AddressLists $AddressList -RoomList $rL -GlobalAddressList $gAL -OfflineAddressBook $oAB"
Write-Host $updatecommand
}

Powershell Like operator invokes REST error

I am working on a custom PoweShell module picked up from the internet for our BI application.
My question is rather simple, the code below does not work:
Get-QlikDataConnection -filter "name -like 'Data*'"
And throws an error like:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\Program Files\WindowsPowerShell\Modules\Qlik-Cli\1.13\functions\core.ps1:32 char:15
+ ... $result = Invoke-RestMethod -Method $method -Uri $path #params -Web ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
However the code below works fine and shows me the correct output:
Get-QlikDataConnection -filter "name eq 'DataPrepAppCache'"
Am I doing something wrong or do some modules not understand a few operators?
After having a look at the source of the module you're using, Qlik-Admin-Utils, I would not use the -filter param, as the input you specify there gets processed by this block within the Invoke-QlikGet cmdlet:
If( $filter ) {
If( $path.contains("?") ) {
$path += "&filter=$filter"
} else {
$path += "?filter=$filter"
}
}
This script appends your filter as a query parameter in the URL, and it doesn't support regular PowerShell formatting, but sends the filter over to qLik's REST API.
If I were writing this, I'd ignore their filtering and do the following:
$Connections = Get-QlikDataConnection
$DataConnection = $Connections | Where name -like "Data*"
This is more likely to just work with less fiddling.
However, if you want to use Qlik's Filter support, I found this so you can read up on the syntax of it here.
It looks like they do offer a filter of their own which might help, it's the Starts With filter, defined as SW, for a syntax of Name sw 'Data'. You might try this and see if it works instead.
Get-QlikDataConnection -filter "name sw 'Data'"

Not able to call out array headers in a foreach loop

Okay - this is a really weird issue - and it probably has a really stupid solution.
But i import a csv
$csv = import-csv c:\users\hello.csv
Then i have an array of words, for which i am wanting to use to search through the csv - and if there's a match in the csv - populate an adjacent column in the csv.
here's the array:
$newhandles
hi
hello
now - if i run a foreach loop with an if statement inside of it - it doesn't recognize one of the headers.
foreach ($newhandle in $newhandles)
{if ($csv.name -eq $newhandle) {$csv.redundant = $newhandle}}
however it gives me this error:
The property 'redundant' cannot be found on this object. Verify that the property exists
and can be set.
At line:1 char:69
+ ... andles) {if ($csv.name -eq $newhandle) {$csv.redundant = $newhandle}}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
I know the property exists - because if i call it directly - it shows three empty slots - and if i call something to it directly - the element will populate. such as
> $csv[0].redundant = 'hi'
> $csv[0]
name : hi
description : don't settle
system : sight
redundant : hi
tags :
Any ideas?
try using this foreach loop :
foreach ($rec in $csv){
if($newhandles -contains $rec.name){
$rec.redundant = $rec.name
}
}
if you check ($csv.redundant).GetType(),you can see that it returns an array instead of the property you want but when you are assigning value to $csv[0].redundant you are accessing the exact property and that's why it works when you tested manually
try this
import-csv "c:\users\hello.csv" | select * , #{N="redundant";E={if ($newhandles -contains $_.Name) {$_.Name} else {$null}}} -ExcludeProperty redundant

copy-item cannot bind argument to parameter 'path' because it is null

This one has me stumped. I have already searched on "copy-item cannot bind argument to parameter 'path' because it is null", and found several posts where the answer involved fixing the syntax so that the first parameter is not null. To the best of my knowledge, my first parameter is not null, and is also of the correct type, and I am still getting the same error. I also have a very similar script running on another server without problems, and which was the template I developed this from.
The script is in a file called 'weekly-archive.ps1' and is being invoked in the PowerShell console by '.\weekly-archive.ps1'.
I am running PowerShell 2.0 on Windows Server 2008 R2
Here is the script segment in question, complete with extra stuff to print the variables before use:
$pathtosource = "\\domainname\backup\servers\windowsimagebackup\"
$pathtodest = "G:\backup\servers\"
$images = Get-ChildItem $pathtodest
foreach ($_ in $images)
{
$sourcepathname = $pathtosource + $_
$destpathname = $pathtodest + $_
$logresult += "`tSaving '" + $sourcepathname + "' to '" + $destpathname + "' at " + (Get-Date).ToShortTimeString() + ".`n"
$sourcepathname
$sourcepathname.GetType()
$pathtodest
$pathtodest.GetType()
Copy-Item $sourchpathname $pathtodest -recurse
$count += 1
}
And here is the resulting output for the first $_ in $images, showing that neither argument is null, and both arguments are actually strings:
PS D:\Administration> .\weekly-archive.ps1
\\domainname\backup\servers\windowsimagebackup\DC-1
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
G:\backup\servers\
True True String System.Object
Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At D:\Administration\weekly-archive.ps1:80 char:12
+ Copy-Item <<<< $sourchpathname $pathtodest -recurse
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand
I also tried using the '-path' and '-destination' flags, which as AFAIK are optional. If I replace '$sourcepathname' in on the copy-item line in the script with a literal string, there is no error.
Finally, the following lines typed directly into the PowerShell Console work perfectly:
$sourcepathname = "\\domainname\backup\servers\windowsimagebackup\DC-1"
$pathtodest = "G:\backup\servers\"
copy-item $sourcepathname $pathtodest -recurse
So, something is clearly wrong with my use of '$sourcepathname', but I can't find it. Please do not hesitate to demonstrate my ignorance....
There is a typo on the copy-item line of the script. You have $sourchpathname and it should be $sourcepathname.