Powershell script saving on UTC time - powershell

i had implemented powershell script for extract data from sharepoint to CSV file. Currently my file was saving as per my time zone. But i want to save the file with UTC time. means under script i want to convert time format my time to UTC time. Can anyone please correct my script. Below script lines i am using.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$web = get-spweb http://testsharepoint/sharepoint/
$caseLib = $web.lists | where {$_.title -eq "Library"}
$query=new-object Microsoft.SharePoint.SPQuery
$query.ViewFields = "<FieldRef Name='LinkFilename'/><FieldRef Name='DocumentSetDescription'/>"
$query.RowLimit=5000
$ListName1 = "Test_"
$ExportFolder1 = “C:\export\”
$ExportName1 = Get-Date -f “yyyyMMdd”
$ExportPath1 = $ExportFolder1 + $ListName1 + $ExportName1 + “.csv”
$ListName = "Data_"
$ExportFolder = “\\servername\Data\”
$ExportName = Get-Date -f “yyyyMMdd”
$ExportPath = $ExportFolder + $ListName + $ExportName + “.csv”
do
{
$caseLibItems=$caseLib.GetItems($query)
$query.ListItemCollectionPosition=$caseLibItems.ListItemCollectionPosition
$listItemsTotal = $caseLibItems.Count
$x = 0
for($x=0;$x -lt $listItemsTotal; $x++)
{
$Description = $caseLibItems[$x]["DocumentSetDescription"]
$str = ""
if('$Description; -ne $null)
$str = $caseLibItems[$x]["LinkFilename"].ToString() + '}' + $Description
}
else
{
$str = $caseLibItems[$x]["LinkFilename"].ToString()
}
Write-Output $str| Out-File $ExportPath1 -Append
}

Quite easy as PowerShell has a .ToUniversalTime() method. Changing the below would be the easiest without changing everything else.
$ExportName = (Get-Date).ToUniversalTime().ToString("yyyyMMdd")
$ExportName1 = (Get-Date).ToUniversalTime().ToString("yyyyMMdd")

Related

Script that doesn't validate argument

I have this script, it searches a Word document for "Detection Method Type", then pulls the value from the 5th line along, say "C:\program files\test\notepad.exe", the script should then split it to $filepath = C:\program files\test and $file = notepad.exe.
I get the following error when trying to pass the above to new-cmdetectionclausefile:
New-CMDetectionClauseFile : Cannot validate argument on parameter 'FileName'. System.Management.Automation.ValidationMetadataException
At line:8 char:70
+ ... new-CMdetectionClauseFile -path $filepathexe -filename $file -Existe ...
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [New-CMDetectionClauseFile], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ConfigurationManagement.PowerShell.Cmdlets.Dcm.NewDetectionClauseFile*
ERROR:
the problem happens with the $file even though it's populated
pre-requisites:
myscript
configurationmanager.ps1
docx that contains: Detection Method Type C:\program files\test\notepad.exe
script:
param($documentPath)
function get-documentclause{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][string]$documentPath
)
$documentPath = "D:\Documents\Packaging Scripts\test.docx"
<#
cells have an end-of-0cell marker of two chars (bytes 13 and 7)
we will need to trim these later
convert bytes to char and join as string
#>
$endOfCellMarker = -join #([char][byte]13, [char][byte]7)
# instantiate Word Com Object
$wordApplication = New-Object -ComObject Word.Application
<#
open the document:
param 1 = FileName
param 2 = ConfirmConversions
param 3 = ReadOnly$doclause
(param 2 only needed because this method accepts only positional parameters)
see https://learn.microsoft.com/en-us/office/vba/api/word.documents.open
#>
$wordDocument = $wordApplication.Documents.Open($documentPath, $false, $true)
$doclause = ""
$regclause = ""
$fileclause = ""
try{
#check to see if document is a table or paragraph
$count = 0
foreach($tables in $wordDocument.Tables){
$count++
}
#if document is true (paragraph) else it will be treated as table
if($count -eq 1){
$count = 0
foreach($para in $wordDocument.Paragraphs){
#Write-Host $para.range.text
#Write-Host "$count"
#$wordtolookfor = $para.Range(3).Text
$word = $para.Range.text
#$word
#pause
if ($word -like "*Detection Method Type*"){
$num = $count + 5
#Write-Host $wordDocument.Paragraphs($num).range.text
$doclause = $wordDocument.Paragraphs($num).range.text
} #end of if
$count++
}#end of foreach
} else {$doclause = $wordDocument.Tables.Item(8).cell(4,2).range.text}
}catch{}
#test if the clause makes sense
$doclause = $doclause.ToString().Trim()
#test if detection method contains exe or registry path
if(($doclause -like "*.exe*") -xor ($doclause -like "*CurrentVersion\Uninstall*")){
if($doclause -like "*.exe*") {
[string]$filepathexe = split-path -parent $doclause
[string]$file = $doclause.Split("\") | Select-Object -last 1
$fileclause = new-CMdetectionClauseFile -path $filepathexe -filename $file -Existence
} #end of exe clause
#if file does contain reg run the following
elseif($doclause -like "*CurrentVersion\Uninstall*") {
#selects the first backslash
$hive = $doclause.Split("\") | Select-Object -First 1
#replaces the underscore withnothing
$hive = $hive.Replace("_","")
#removes the first 4 characters HKEY
$hive = $hive.substring(4)
#produce the rest of the key
$path = $doclause.Split("\") | Select-Object -last 7
$path = $path -join "\"
$path = Split-Path $path -Parent
#get final value
$regvalue = Split-Path -Leaf $doclause
$regclause = New-CMDetectionClauseRegistryKeyValue -Hive $hive -KeyName $path -PropertyType String -ValueName $regvalue -Existence
} #end of reg clause
else {
$regclause = ""
$fileclause = ""
}
} #end of testing clause
else {$doclause = ""}
$nothing = ""
# close the file and do not save changes
$wordDocument.Close([ref] [Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges)
# end the WINWORD.EXE process
$wordApplication.Quit()
if($regclause){
return $regclause
#return #($hive,$path,$regvalue) this works but testing if previous would have worked too
}
elseif($fileclause){return $fileclause}
else {
Return $nothing
$regclause = ""
$fileclause = ""
}
}
answer found
before
$fileclause = new-CMdetectionClauseFile -path $filepathexe -filename $file -Existence
add:
$asd = [string]$file -replace"\u007",""
$asd2 = [string]$asd -replace"t|n|r",""`
then change
$fileclause = new-CMdetectionClauseFile -path $filepathexe -filename $asd2 -Existence
exporting $file to a text file you get the expect result plus a "[]" symbol, loading that in to notepad++ it can be resolved to 0007 which is Unicode for a bell symbol, remove that and what not.

Mirth Property File Corrupted on Editing using powershell

I am trying to edit the Mirth property file to add microsoft sql server driver url and class name using powershell. I am able to edit and save . When I start the Mirth services after editing, the Mirth property file is corrupted. But I reviewed both the original and the edited content. Everything is the same except the added changes and the file size is increased from 5kb to 10 kb. Can anyone help me out? Here is the powershell script.
$server="Localhost"
$PropertyfilePath = "C:\Program Files\Mirth Connect\conf\mirth.properties"
$connectionString = "jdbc:sqlserver://$($server):1433;instanceName=$($server);databaseName=Mydb;integratedSecurity=true"
$driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
$data= #()
Copy-Item $PropertyfilePath "D:\Mirthbackup" -force
$newstreamreader = New-Object System.IO.StreamReader($PropertyfilePath)
[int]$eachlinenumber = 1
while (($readeachline = $newstreamreader.ReadLine()) -ne $null)
{
if($readeachline.Contains("= derby")){
$readeachline.Remove(0)
$update= "database = sqlserver"
$data +=$update
$eachlinenumber++
}
elseif($readeachline.Contains("database.url"))
{
$update=$readeachline.Substring(0,12)+" = "+$connectionString
$data +=$update
$eachlinenumber++
}
elseif($readeachline.Contains(".driver"))
{
$readeachline.Remove(0)
$update ="database.driver = "+$driverName
$data +=$update
$eachlinenumber++
}
else{
$data +=$readeachline
$eachlinenumber++
}
}
$newstreamreader.Dispose()
$data | Out-File -FilePath $PropertyfilePath
Your properties file should be ISO-8859-1 (latin1) encoded.
Try to change your code to:
$server="Localhost"
$PropertyfilePath = "C:\Program Files\Mirth Connect\conf\mirth.properties"
$connectionString = "jdbc:sqlserver://$($server):1433;instanceName=$($server);databaseName=Mydb;integratedSecurity=true"
$driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
$data= #()
Copy-Item $PropertyfilePath "D:\Mirthbackup" -force
$encoding = [System.Text.Encoding]::GetEncoding('iso-8859-1'))
$newstreamreader = New-Object System.IO.StreamReader($PropertyfilePath, $encoding)
[int]$eachlinenumber = 1
while (($readeachline = $newstreamreader.ReadLine()) -ne $null)
{
# if statements left out
}
$newstreamreader.Dispose()
[System.IO.File]::WriteAllLines($PropertyfilePath,$data, $encoding)

How to handle create a file and write it using Powershell?

I want to create a file and write content to the file.
The new file will create based on the total SWPO file exist. I tried this scirpt, I can create new file. But when I put only 1 $PO_Path file, it will create 2 new file. Actually those 2 file are the same but one of the file without $c. Like this
ID_ABC18XXR3CT123_.job
ID_ABC18XXR3CT123_AE.job
BUt if I put $PO_Path file more than 1, it works well.
Anyone can help me please. Thanks.
Function Create_OriJob
{
$BID = "18XXR3CT123"
$Job_Path = $Config_File.Automation_Config.Path.OriJob
$PO_Path = $Config_File.Automation_Config.Path.POfiles
if(Test-Path -Path "$PO_Path\*$BID*")
{
Write-Output "SWPO File Found"
# Start-Sleep -s 3
$PO_Content = Get-Content -path "$PO_Path\*$BID*"
$POfile = Get-ChildItem -Name "$PO_Path\*$BID*"
$Get_CRM = $PO_Content | Where-Object {$_ -like "*;CRM*"}
$CRM = $Get_CRM.Substring(5,2)
$CRM = $CRM.split()
$POCountry = Get-ChildItem -Name "$PO_Path"
$GetCountry = $POCountry.Substring(15,3)
$GetCountry = $GetCountry.split()
For($i = 0; $i -lt $POfile.Length; $i++){
try{
$po = $POfile[$i]
$c = $CRM[$i]
$cc = $GetCountry[$i]
New-Item -ItemType File -Path "$Job_Path\$JobType`_$Prefix$BID`_$c.job" -Force
$Title = $Config_File.Automation_Config.Out_Job.Title
$Auto = $Config_File.Automation_Config.Out_Job.Auto
$Proc = $Config_File.Automation_Config.Out_Job.Process
$Auto = $Config_File.Automation_Config.Out_Job.Auto
$PO_Conf = $Config_File.Automation_Config.Out_Job.PO
$BIDINFO = $Config_File.Automation_Config.Out_Job.BIDINFO
$BuildID = $Config_File.Automation_Config.Out_Job.BID
$PFX = $Config_File.Automation_Config.Out_Job.PFX
$CRM_Conf = $Config_File.Automation_Config.Out_Job.CRM
$CountryConf = $Config_File.Automation_Config.Out_Job.Country
$Platform = $Config_File.Automation_Config.Out_Job.Platform
$TSJobcreate = Get-Date
$Output_JOB = #"
<?xml version="1.0" encoding="UTF-8"?>
<$Title>
<$Auto>
<$Proc>$Auto</$Proc>
<$PO_Conf>$po</$PO_Conf>
</$Auto>
<$BIDINFO>
<$BuildID>$BID</$BuildID>
<$PFX>$Prefix</$PFX>
<$CRM_Conf>$c</$CRM_Conf>
<$CountryConf>$cc</$CountryConf>
</$BIDINFO>
<$Platform>
$All_SSID
</$Platform>
<Timestamp>
<JobCreate>$TSJobcreate</JobCreate>
</Timestamp>
</$Title>
"#
$Output_JOB | Out-File "$Job_Path\$JobType`_$Prefix$BID`_$c.job" -NoNewline
Write-Host "Output"
}
catch{
Write-Output "Something wrong!"
}
}
Write-Output "Continue to create operational job"
Create_OpJob
}
else{
Write-Host "SWPO Not Found, Do Error checking file"
Error_Monitoring
}
#Error_Monitoring
}

run and handle output from ps1 script

The goal : get all logged in / logged out users from the system.
Those users who logged in / logged out by using remote desktop connection.
My script :
Param(
[array]$ServersToQuery = (hostname),
[datetime]$StartTime = "January 1, 1970"
)
foreach ($Server in $ServersToQuery) {
$LogFilter = #{
LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
ID = 21, 23, 24, 25
StartTime = $StartTime
}
$AllEntries = Get-WinEvent -FilterHashtable $LogFilter -ComputerName $Server
$AllEntries | Foreach {
$entry = [xml]$_.ToXml()
[array]$Output += New-Object PSObject -Property #{
TimeCreated = $_.TimeCreated
User = $entry.Event.UserData.EventXML.User
IPAddress = $entry.Event.UserData.EventXML.Address
EventID = $entry.Event.System.EventID
ServerName = $Server
}
}
}
$FilteredOutput += $Output | Select TimeCreated, User, ServerName, IPAddress, #{Name='Action';Expression={
if ($_.EventID -eq '21'){"logon"}
if ($_.EventID -eq '22'){"Shell start"}
if ($_.EventID -eq '23'){"logoff"}
if ($_.EventID -eq '24'){"disconnected"}
if ($_.EventID -eq '25'){"reconnection"}
}
}
$Date = (Get-Date -Format s) -replace ":", "."
$FilePath = "$env:USERPROFILE\Desktop\$Date`_RDP_Report.csv"
$FilteredOutput | Sort TimeCreated | Export-Csv $FilePath -NoTypeInformation
Write-host "Writing File: $FilePath" -ForegroundColor Cyan
Write-host "Done!" -ForegroundColor Cyan
#End
I really do not understand ps1 scripts. I've found this script but i want to use it for my purposes.
When i try to execute it with c# :
Scenario 1 :
string scriptText = "C:\\MyPath\\script.ps1";
try
{
Runspace runspace = RunspaceFactory.CreateRunspace();
// open it
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
Collection<PSObject> results = pipeline.Invoke();
It throws an error :
ps1 is not digitally signed.
Second scenario :
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript(str_Path);
Collection<PSObject> PSOutput = PowerShellInstance.Invoke();
if (PowerShellInstance.Streams.Error.Count > 0)
{
// error records were written to the error stream.
// do something with the items found.
}
}
Streams are always empty. Actually it always count 0 rows.
Any idea/suggestion how to get this done ?
I used Write-Output instead of Write-Host into the end of the script without generating csv file. Credits to this.

Powershell Timeout After two Seconds

I'm new to powershell. I read some lines on www.powershell.com. Now I need your help to solve a problem. I want to read the UUID from clients in the Network. Therefore I created a document "pcs.txt" where all PCs are stored.
$pc = Get-Content pcs.txt #Read content of file
$cred = Get-Credential “domain\user”
for ($i=0; $i -lt $pc.length; $i++) {
$Result=test-connection -ComputerName $pc[$i] -Count 1 -Quiet
If ($Result -eq 'True')
{
$uuid = (Get-WmiObject Win32_ComputerSystemProduct -ComputerName $pc[$i] -Credential $cred).UUID
$Ausgabe=$pc[$i] + ';'+$uuid
$Ausgabe
}
else
{
$Ausgabe=$pc[$i] + '; UUID nicht erhalten'
$Ausgabe
}
}
First I test if the ping works. When the ping works I try to get the uuid.
Sometimes I don't get the uuid even if the ping worked. So I would like to code a timeout, which say -> go to next pc when you don't have the uuid after 2 seconds.
Can you help me please?
Alas, there is no timeout parameter for Get-WmiObject commandlet. There is a feature request in MS Connect, but it is from 2011 and still open.
A workaround, which I haven't tested is available by using System.Management. I'll copy-and-paste it here in case the link goes dead. (And I hate SO answers that only contain links to resouces that may or may not exist...)
Function Get-WmiCustom([string]$computername,[string]$namespace,[string]$class,[int]$timeout=15){
$ConnectionOptions = new-object System.Management.ConnectionOptions
$EnumerationOptions = new-object System.Management.EnumerationOptions
$timeoutseconds = new-timespan -seconds $timeout
$EnumerationOptions.set_timeout($timeoutseconds)
$assembledpath = "\\" + $computername + "\" + $namespace
#write-host $assembledpath -foregroundcolor yellow
$Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions
$Scope.Connect()
$querystring = "SELECT * FROM " + $class
#write-host $querystring
$query = new-object System.Management.ObjectQuery $querystring
$searcher = new-object System.Management.ManagementObjectSearcher
$searcher.set_options($EnumerationOptions)
$searcher.Query = $querystring
$searcher.Scope = $Scope
trap { $_ } $result = $searcher.get()
return $result
}
I found a good workaround!
http://theolddogscriptingblog.wordpress.com/2012/05/11/wmi-hangs-and-how-to-avoid-them/
Here my working code:
$pc = Get-Content pcs.txt #FILE FROM THE HARDDISK
$cred = Get-Credential “DOMAIN\USER” #
for ($i=0; $i -lt $pc.length; $i++)
{
$Result=test-connection -ComputerName $pc[$i] -Count 1 -Quiet
If ($Result -eq 'True')
{
$WMIJob = Get-WmiObject Win32_ComputerSystemProduct -ComputerName $pc[$i] -Credential $cred -AsJob
$Timeout=Wait-Job -ID $WMIJob.ID -Timeout 1 # the Job times out after 1 seconds.
$uuid = Receive-Job $WMIJob.ID
if ($uuid -ne $null)
{
$Wert =$uuid.UUID
$Ausgabe=$pc[$i] + ';'+$Wert
$Ausgabe
}
else
{
<#$b = $error | select Exception
$E = $b -split (:)
$x = $E[1]
$Error.Clear() #>
$Ausgabe=$pc[$i] + '; got no uuid'
$Ausgabe
}
}
else
{
$Ausgabe='PC not reached through ping.'
$Ausgabe
}
}
I hope I can help somebody with that