New-Object cannot contain a dash (-) but "needs to" - powershell

I am creating a new object for export values to CSV:
New-Object -TypeName PSObject -Property #{
host_name = ($server.name).ToLower()
address = $IPAddress
host_is_collector = "no"
host-preset = "windows-server"
} | Select-Object host_name,address,host-preset | Export-Csv -Path $nConf_import_host_file
The problem is that one of the lines contains a dash (host-preset). I would ofcourse simply change it to an underscore, but my CSV needs this value to be a dash. I could also do a -replace on the entire csv after it has been created but that seems dirty.
Is there a way I can use dash here?
My error msg is:
Missing '=' operator after key in hash literal.
At Z:\Scripts\Testscripts\ScanServers_and_check_nagiosV7.ps1:336 char:16
+ host-preset <<<< = "windows-server"
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEqualsInHashLiteral

You simply need to treat the host-preset property name as a string by enclosing it in quotes:
New-Object -TypeName PSObject -Property #{ "host-preset" = "windows-server" }

Related

InvalidArgument when Invoking Expression containing get-date

Whenever i try to invoke the following String
$log = "Get-EventLog -LogName " + $name + " -EntryType Error -After " + $datum + " | Format-List -Property TimeWritten,Message"
i get an error
+ ... gName Application -EntryType Error -After 03/08/2021 11:51:37 | Forma ...
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-EventLog], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetEventLogCommand
The $datum variable is filled like this
$datum = $((get-date).AddDays(-10))
As the error indicates, $datum expands to a string with a space in between the date and time parts - you need to add quotes around it.
Instead of showing you how to quote it, I'm gonna show you a better way:
Use splatting instead of Invoke-Expression:
$logParams = #{
LogName = $name
EntryType = 'Error'
After = $datum
}
Get-EventLog #logParams |Format-List -Property TimeWritten,Message
Now we don't need to worry about quoting or qualifying parameter argument values, PowerShell binds them correctly for us.

How To Create An Array Reading from Host? [duplicate]

This question already has answers here:
Parsing a file to create an array of lines
(2 answers)
Closed 3 years ago.
I am creating a script that will allow batch creation of new users but am running into an issue with the creation of the array.
$fname = #()
$lname = #()
$i = 0
$fname[$i] = Read-Host "`nWhat is the first name of the new user?"
$fname[$i] = $fname[$i].trim()
$lname[$i] = Read-Host "What is the last name of the new user?"
$lname[$i] = $lname[$i].trim()
If I run this I get the error:
Index was outside the bounds of the array.
At line:1 char:1
+ $fname[$i] = Read-Host "`nWhat is the first name of the new user?"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException
Method invocation failed because [System.Object[]] does not contain a method named 'trim'.
At line:2 char:13
+ $fname[$i] = $fname.trim()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
You are creating an array with an fixed size of zero. As $fname[0] doesn't exist in the array you can't change it's value. One solution would be to use += to add an element to your existing array:
$fname = #()
$lname = #()
$i = 0
$fname += Read-Host "`nWhat is the first name of the new user?"
$fname[$i] = $fname[$i].trim()
$lname += Read-Host "What is the last name of the new user?"
$lname[$i] = $lname[$i].trim()
As a side note, I personally wouldn't use different arrays for my user information but instead create PSCustomObject:
$UserTable = #()
$obj = New-Object psobject
$obj | Add-Member -MemberType NoteProperty -Name FirstName -Value (Read-Host "`nWhat is the first name of the new user?").Trim()
$obj | Add-Member -MemberType NoteProperty -Name LastName -Value (Read-Host "What is the last name of the new user?").Trim()
$UserTable += $obj
$i = 0
$UserTable[$i].FirstName
$UserTable[$i].LastName

How to escape a badly-named property using PowerShell in Azure Web App app settings

I have a set of Azure Web App properties gathered by
$properties = (Invoke-AzureRMResourceAction -ResourceGroupName $ResourceGroup
-ResourceType Microsoft.Web/sites/Config -Name $Site/appsettings
-Action list -ApiVersion 2015-08-01 -Force).Properties
Also, I've made a hash table to store these properties
$hashtable = #{}
$properties | Get-Member -MemberType NoteProperty | % { $hashtable[$_.Name] = $properties.($_.Name) }
The problem I've faced is to change the badly formatted property to a new value:
PS C:\> $hashtable
Name Value
---- -----
AzureAd:ClientId XXXXXX-1621-42ff-85cd-XXXXXXXXX
PS C:\> $hashtable.AzureAd:ClientId = "YYYYYY-1621-42ff-85cd-YYYYYYYY"
At line:1 char:14
+ $hashtable.AzureAd:ClientId = "YYYYYY-1621-42ff-85cd-YYYYYYY ...
+ ~~~~
Unexpected token ':ClientId' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
So the command Set-AzureRMWebApp -Name $Site -AppSettings $hashtable isn't needed.
Is there a chance to escape the poor property in order to execute the script or should I next be careful when choosing the right app settings name\variable?
You can enclose the properties within double quotes like this -
$hashtable."AzureAd:ClientId" = "YYYYYY-1621-42ff-85cd-YYYYYYYY"
You can also use single quotes('') since there is no variable to be substituted in your property -
$hashtable.'AzureAd:ClientId' = "YYYYYY-1621-42ff-85cd-YYYYYYYY"

Starting/Stopping AWS EC2 Instances using AWS Powershell Tools

I am attempting to write two separate scripts. One script determines which EC2 instances are stopped, it starts them and documents what it starts to a text file.
The second script will read the text file and stop those instances. For debugging/simplicty sake I am starting out by combining the two scripts into a single script.
Here's my script:
$Instances = (Get-EC2Instance).instances
$start_instances = #()
$Instances | foreach {
$state = Get-EC2InstanceStatus -InstanceId $_.InstanceId -IncludeAllInstance $true
$state = $state.InstanceState.Name
if ($state -eq "stopped"){
$start_instances += $_.InstanceId
}
}
[System.IO.File]::WriteAllText("C:\users\myusername\desktop\so.csv", $($start_instances -join ','))
$shutdown_instances = [System.IO.File]::ReadAllText("C:\users\myusername\desktop\so.csv")
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Stop-EC2Instance -Instance $shutdown_instances
Starting and documenting what instances are running works fine. Its the stopping instances which is failing.
I'm getting the following error:
Stop-EC2Instance : Invalid id: "i-99edd755,i-8d647f58"
At C:\users\myusername\Desktop\aws-test.ps1:28 char:1
+ Stop-EC2Instance -Instance $shutdown_instances
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Stop-EC2Instance], AmazonEC2Exception
+ FullyQualifiedErrorId : Amazon.EC2.AmazonEC2Exception,Amazon.PowerShell.Cmdlets.EC2.StopEC2InstanceCmdl
Those instance IDs are indeed valid so I can't figure out why the heck its complaining. I was writing the instance IDs to a file via out-file and getting it via get-content but that seemed to have caused a different error.
I'm assuming the issue has something to do with the format of the data once i'm pulling it out of the text file.
Edit
So I've changed my script to:
$start_instances = $start_instances | Select-Object #{Name='Name';Expression={$_}}
$start_instances | Export-Csv -Delimiter ',' -NoTypeInformation -path C:\temp\instances.csv
$stop_instances = #(Import-Csv -path C:\temp\instances.csv)
$stop_instances | Stop-EC2Instance
But still get an error:
Stop-EC2Instance : No instances specified
At C:\temp\aws-test.ps1:22 char:19
+ $stop_instances | Stop-EC2Instance
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Stop-EC2Instance], AmazonEC2Exception
+ FullyQualifiedErrorId : Amazon.EC2.AmazonEC2Exception,Amazon.PowerShell.Cmdlets.EC2.StopEC2InstanceCmdlet
I've also tried:
Stop-EC2Instance -InstanceID $stop_instances
But that also dies:
Stop-EC2Instance : No instances specified
At C:\temp\aws-test.ps1:22 char:1
+ Stop-EC2Instance -InstanceId $stop_instances
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Stop-EC2Instance], AmazonEC2Exception
+ FullyQualifiedErrorId : Amazon.EC2.AmazonEC2Exception,Amazon.PowerShell.Cmdlets.EC2.StopEC2InstanceCmdlet
InstanceId parameter needs array.
You can declare an empty array first
$EC2Instance =#()
Then use Import-CSV and pipe it to append the empty array with each value from csv
Import-CSV C:\Temp\Instance.csv | Foreach-Object {$EC2Instance += $_.InstanceId}
echo $EC2Instance
$EC2instance will now have the required instance id's in an array
Then you can use it in the command
Stop-EC2instance -InstanceId $EC2instance
This worked for me.

Argument errors with office 365 cmdlet

I'm having issues feeding variables into the New-MsolUser cmdlet. I'm getting the following error.
New-MsolUser : A positional parameter cannot be found that accepts argument 'â?UserPrincipalName ausertest#test.ie â?UsageLocation'.
At C:\users\test\Documents\test.ps1:148 char:1
+ New-MsolUser -DisplayName $TargetFullname â?"UserPrincipalName $TargetEmail â?" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-MsolUser], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.Online.Administration.Automation.NewUser
The code I am using is:
$Source = "AnotherADUser"
$TargetFname = "New"
$TargetLname = "User"
$Target = "ausertest"
$TargetFullname = [string]::Concat($TargetFname ," ", $TargetLname)
$SourceEmail = (Get-ADUser $source -Property EmailAddress).EmailAddress
$SourceDomain = $SourceEmail.split("#")[1]
$TargetEmail = ([string]::Concat($Target , "#" , $SourceDomain))
New-MsolUser -DisplayName $TargetFullname –UserPrincipalName $TargetEmail –UsageLocation "IE" | Set-MsolUserLicense -AddLicenses "TESTINSTALL:EXCHANGESTANDARD"
This command works when I hardcode the details..
–UserPrincipalName and –UsageLocation use not the minus character but the
character with code 8211. Maybe it's fine but try to use the standard minus
instead, just to be sure.