Using powershell to manipulate URL header with real live system data - powershell

I am trying to use powershell to manipulate a url value for a command program that is accessing a web Url.
Basically the case is like this
run in Powershell:
Program Argument https://www.example.com/dash/926846/l.php?link=bTP77O5LyLorxCtjnkdE0g&sectime=1598048132
The Sectime is in Unix time format. What i am trying to do is :
use the powershell command (Get-Date -Date ((Get-Date).DateTime) -UFormat %s) to generate the system time in real time,
Append the result to the end of the Url as a value for sectime.
I tried to concatnate the arguments using call operator :
Arg1=program
Arg2=parameter
Arg3=Url
& $Arg1 Arg2 $Arg3
now the issue is i can do
this is the issue. & $Arg1 Arg2 $Arg3 and that works , but i can not modify the URL to take the real time command (Get- Date -Date ((Get-Date).DateTime) -UFormat %s)
if i split the URL arg into two i cant not concatnate them like this
"https://www.example.com/dash/926846/l.php?link=bTP77O5LyLorxCtjnkdE0g&sectime=(Get-Date -Date ((Get-Date).DateTime) -UFormat %s)."
Since it is a string and an command
An idea how to do this?

$uriTemplate = 'https://www.example.com/dash/{0}/l.php?link={1}&sectime={2}'
$id = '926846'
$link = 'bTP77O5LyLorxCtjnkdE0g'
$timeunixseconds = [System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds().ToString()
$uriSting = [String]::Format($uriTemplate, # Template with placeholders {0}, {1}, {2}...
$id, # first argument goes {0}
$link, # second goes {1}
$timeunixseconds ) # third goes {2}, etc etc
$isUriOk = [System.Uri]::IsWellFormedUriString($uriSting, [System.UriKind]::Absolute)
DateTimeOffset class starting with some .net version (4.5th .net, 5th powershell, AFAIR) has To(From)UnixTimeSeconds and To(From)UnixTimeMilliseconds methods.
DateTime (and Get-Date, which returns DateTime) does not have such methods! Use DateTimeOffset.
And for your original case:
Inside double-quoted strings, variables (even simple, in my opinion) should be added in $() brackets:
"Hello, $($env:USERNAME), it's $(Get-Date -Format 'D') today!"
# Hello, User1, it's Aug 22 2020 today!
Single variables can be added without $() syntax, but I'd recommed add $() always.
Inside single-quoted strings, $() or $var does not work:
'Hello, $($env:USERNAME), it is $(Get-Date -Format "D") today!'
# Hello, $($env:USERNAME), it is $(Get-Date -Format "D") today!

Related

What $ sign indicates in a folder path in powershell?

I have a powershell script that has a two $ signs like this :
$folderDest= '/Home/Vars/Cust/V1/Ex/Res/$toDo/$done'
what $toDo and $done stand for?
Note: I don't have these variables anywhere in the script.
Edit: The code below.
$month = Get-Date -Format yyyy-MM
$ftppath = $folderDest+ "/" + $month + "/*$xttz.txt"
$folderDest= '/Home/Vars/Cust/V1/Ex/Res/$toDo/$done'
In PowerShell the value of $folderDest will be interpreted as:
/Home/Vars/Cust/V1/Ex/Res/$toDo/$done
This is due to the single quotes around it as defined in this post.

Remove space between objects when using Write-Host

I have a text file that has something like this:
Year= YYYY
Month= MM
I then read the file in, select the line I want, split the line so I only get what is to the right of the "=" sign, trim blank spaces, and put it all into a variable with this code:
$Year=Get-Content -Path .\test.txt | Where-Object {$_ -match 'Year='}
$Year=($Year -Split 'Year=').trim()
The above code is repeated for each setting I have (i.e. Year, Month, Day, Time).
When I put $Year into the command prompt I get "YYYY" (No leading space); but when I use Write-Host I get " YYYY" (has a leading space).
It is important that I be able to put $Year $Month next to eathother without a space for filepath and file naming reasons. (i.e. .\YYYY\MM or YYYYMM.txt).
I have tried:
Write-Host "Example: $Year\$Month"
Write-Host "Example: " $Year "\" $Month
Write-Host ("Example: $($Year)\$($Month)")
Write-Host "Example: $Year\" + $Month"
Write-Host "Example: $Year\" -f $Month"
....and several ways of implementing .trim() with no success.
If the problem is not in the Write-Host line, then the only other thing I can think of is that it must be with how the data is written into the variables. Please keep in mind, this is only an example, my actual problem is larger. This is just a simple example of what I need to accomplish.
QUICK UPDATE:
I found a long workaround like this:
Write-Host "$Year\" -nonewline
Write-Host "$Month\".trim() -nonewline
Write-Host "$Day\".trim() -nonewline
BUT there has to be a better way to do this. I am using about 8 variables in my actual code. So to give 1 example of a filename and path would be 8 lines long...which would be dumb.
The problem is that $Year -Split 'Year=' returns 2 elements, not just the string after Year=.
An immediate fix would be:
$Year = ($Year -Split 'Year=')[1].Trim()
More generally, you could write:
$Year = ($Year -split '=', 2)[1].Trim()
As for what you tried:
If the -split operator finds the separator string at the very start of the string too, it assumes that what precedes it is the first substring to return, which is the empty string in this case.
In your case, 'Year= YYYY' -split 'Year=' effectively yields array '', ' YYYY', and calling .Trim() on it trims the individual elements, so you end up with '', 'YYYY'.
If you print that to the console via PowerShell's implicit output, you can get an empty line, followed by YYYY, which is also what you would get if you used Write-Output $Year.
By contrast, if you use Write-Host, PowerShell stringifies the array by concatenating its elements with spaces (by default, can be changed with $OFS), so you got  YYYY.
To put it differently:
PS> Write-Host ('', 'YYYY')
YYYY # concatenation of: empty string, space, 'YYYY'
is by default implicitly the same as:
PS> Write-Host (('', 'YYYY') -join ' ')
YYYY

Culture based formatting of time variable

In this example it seems to me that the first two outputs should match, giving me formatting based on my defined culture. The last should be different because French formatting is different. Instead, the last two are the same, and are both getting some kind of default formatting. So, how do I do Culture based formatting when the time is a variable rather than formatting directly with Get-Date? It seems like it should be the same, but it's not.
get-date -format ((Get-Culture).DateTimeFormat.FullDateTimePattern)
$time = Get-Date
$pattern = 'FullDateTimePattern'
$formattedTime = $time -f (Get-Culture).DateTimeFormat.$pattern
Write-Host "$formattedTime"
$culture = New-Object system.globalization.cultureinfo('fr-FR')
$formattedTime = $time -f ($culture).DateTimeFormat.$pattern
Write-Host "$formattedTime"
The output I get is
July 9, 2019 11:22:01 AM
07/09/2019 11:22:01
07/09/2019 11:22:01
What I want to get is
July 9, 2019 11:26:46 AM
July 9, 2019 11:26:46 AM
Tuesday 9 July 2019 11:26:46
EDIT: So, based on I.T Delinquent's response, I tried this
$pattern = 'longDateTimePattern'
$date = Get-Date
$format = (Get-Culture).DateTimeFormat.$pattern
$string = ($date).ToString($format)
Write-Host $string
$culture = New-Object system.globalization.cultureinfo('de-DE')
$format = $culture.DateTimeFormat.$pattern
$string = ($date).ToString($format)
Write-Host $string
And it gave me identical results. Because it's not 'longDateTimePattern', its 'longDatePattern'. Given that the pattern could become a user supplied string, I better validate them.
Your attempt at using the -f operator is flawed (see bottom section).
To get the desired output, use the [datetime] type's appropriate .ToString() overload:
$time.ToString($culture.DateTimeFormat.$pattern, $culture)
Passing $culture as the 2nd argument ensures that the formatting is applied in the context of that culture.
If your intent is truly to use a format from another culture and apply it in the context of the current culture, simply omit the 2nd argument (as an alternative to the Get-Date -Format approach in your question):
$time.ToString($culture.DateTimeFormat.$pattern)
If there's no need to involve a different culture, the task becomes much simpler, by way of the standard date-time format strings, where single-character strings such as "D" refer to standard formats, such as LongDatePattern:
$time.ToString("D")
You can also pass these strings to Get-Date -Format
Get-Date -Format D
As for what you tried:
In order for the -f operator to work correctly, your LHS must be a string template with placeholders ({0} for the first one, {1} for the second, ...), to be replaced with the RHS operands.
Using a simple example:
Format the RHS, an [int], as a number with 2 decimal places.
PS> '{0:N2}' -f 1
1.00
Therefore, $time -f (Get-Culture).DateTimeFormat.$pattern doesn't perform (explicit) formatting at all, because the LHS - $time - contains no placeholders.
That is, the RHS is ignored, and the LHS is returned as a string: It is effectively the same as calling $time.ToString() in the context of the invariant culture (because the result of applying the -f operator is always a string and PowerShell uses the invariant culture in many string-related contexts).
While you can incorporate a specific date-time format string into a template-string placeholder - by following the placeholder index with : and a format string, as shown above ({0:N2}) - you cannot also provide a culture context for it.
You'd have to (temporarily) switch to the desired culture first:
# Save the currently effective culture and switch to the French culture
$prev = [cultureinfo]::CurrentCulture
[cultureinfo]::CurrentCulture = 'fr-FR'
# Format with the desired format string.
"{0:$($culture.DateTimeFormat.$pattern)}" -f $time
[cultureinfo]::CurrentCulture = $prev
I think this has something to do with how the Get-Date is passed using the variable, it seems to lose the format capability. In fact, if you try using Write-Host ($date -Format $format) gives an error:
Unexpected token '$format' in expression or statement
Here are my setup variables:
$pattern = 'FullDateTimePattern'
$format = (Get-Culture).DateTimeFormat.$pattern
$date = Get-Date
As stated above, using Write-Host ($date -f $format) and incorrectly outputs 07/09/2019 12:24:38. However, using any of the below options does work and correctly outputs 09 July 2019 12:24:38:
Write-Host (Get-Date -Format $format)
Write-Host (Get-Date).ToString($format)
Write-Host ($date).ToString($format)
Hope this helps :)

PowerShell - formatting date to yyMMdd format

I run a PowerShell script that passes a parameter, such as "20160428".
I need to format this into yyMMdd (i.e., getting "160428" as the result). I could just strip out the "20", but I would like to get this right. For such I did so many attempts, such as:
#$COBDATE= '{0:yyMMdd}' -f $COBDATE
#$COBDATE = ([datetime]::ParseExact($COBDATE, "yyMMdd", [System.Globalization.CultureInfo]::InvariantCulture )).DayOfWeek
And the last one:
$COBDATE = ("{0:yyMMdd}" -f [datetime]::parse($COBDATE))
The below works, but once I replace "Get-Date" by my date "20160428" it just prints out the yyMMdd string.
$b = (Get-Date).AddDays(-1).ToString("yyMMdd")
So if I try this:
$input = "20160428"
$format = "yyMMdd"
$input_toDate_up = [DateTime]::ParseExact($input, $format, $null).ToString($format)
$input_toDate_up
It just says that the string is not a valid Date Time, which seems to be the root cause.
How can I fix this?
$Input = "20160428"
Get-Date -Year $Input.Substring(0,4) -Month $Input.Substring(4,2) -Day $Input.Substring(6,2) -Format "yyMMdd"
I think for one $input is a reserved variable so you shouldn't use it as nothing will really work in there as you expect. See here about_Automatic_Variables
I have used this drawn out substring process before with varied abstract date formats.
$dateinput = "20160428"
$dateformat = "yyMMdd"
Get-Date($dateinput.Substring(4,2) + "/" + $dateinput.Substring(2,2) + "/" + $dateinput.substring(0,4)) -Format $dateformat
I'm sure there is a shorter regex method, but that is not under my hat yet.

Special characters in PowerShell

I am trying to work with PowerShell and have it output the copyright character into a Microsoft Word document. For example, the code listed below is what I am trying to use and it is not working.
$SummaryPara.Range.Text = "© "
$SummaryPara.Range.Text = "Get-Date -Format yyyy"
$SummaryPara.Range.Text = " - Name of Org Here "
$SummaryPara.Range.InsertParagraphAfter()
Do I need to use the Alt + 0169 sequence somehow?
I am not sure what I am doing wrong since the following code seems to work:
$selection.TypeParagraph()
$selection.TypeText("© ")
$selection.TypeText((Get-Date -Format yyyy))
$selection.TypeText(" - Name of Org Here ")
$selection.TypeParagraph()
How can I make this work for both the copyright character and other similar special characters?
There are a few problems here. I'll list those and address each:
You can get any character you need by casting the Unicode representation to a char. In this case
[char]0x00A9
You assign a new value to $SummaryPara.Range.Text three times. So, you are overwriting the previous value each time, instead of concatenating ('+' operator), which I think is what you were trying to do.
You are trying to use the cmdlet Get-Date, but since you have quoted it, you will end up with the literal string "Get-Date -Format yyyy", instead of the result of the cmdlet.
Putting it all together, I think you want something like this:
$word = New-Object -ComObject Word.Application
$doc = $word.Documents.Add()
$SummaryPara = $doc.Content.Paragraphs.Add()
$SummaryPara.Range.Text = [char]0x00A9 + ($date = Get-Date -Format yyyy) + " - Name of Org Here "
$word.Visible = $true