Simplify Get-Messagetrackinglog with a new function including MB Conversion - powershell

i want to create a custom function to simplify the get-messagetrackinglog commandlet.
It's nothing complicated, but simplifies the query a little bit.
The function works correctly, but i want to convert the totalbytes to Kilobyte in the function, if desired.
function Get-ExchangeMessagetrackinglog {
.Synopsys
.Description
.Example
Get-ExchangeMessagetrackinglog -Recipient "user#tld.com" -Sender "sender#tld.com" -Begin "01/04/2014" -Ende "05/05/2014" | select Timestamp,Sender,Recipients,Messagesubject,#{label="Kilobytes";Expression={[int]($_.totalbytes/1kb)} }| ft -auto
param(
[String]$ExchangeConnector = "*",
[String]$Begin=(get-date).AddDays(-120),
[Datetime]$Ende=(get-date -uformat "%m/%d/%y %T"),
[String]$Recipient = "*",
[String]$Sender = "*",
[String]$EventID = "Receive",
[String]$Source = "SMTP"
)
Get-Exchangeserver | `
where { $_.isHubTransportServer -eq $True -or $_.isMailboxServer -eq $True } | `
get-messagetrackinglog -Start $Begin -End $Ende -ResultSize Unlimited | `
where-object { `
$_.recipients -like $Recipient -and `
$_.sender -like $Sender -and `
$_.EventID -eq $EventID -and `
$_.Source -like $Source -and `
$_.connectorID -like $ExchangeConnector}
}
My Question:
Is it possible to simplify the function call (.example) ?
I'm not familiar in creating custom objects, but it is possible to create an totalkilobytes object.
Thanks!

Rather than creating a new PSCustom object my answer amends your and returns a string return ("TotalKB: " + $totalKB) as your final total. I also moved the entire select Timestamp.. block into the body of main function.
function Get-ExchangeMessagetrackinglog {
.Synopsys
.Description
.Example
Get-ExchangeMessagetrackinglog -Recipient "user#tld.com" -Sender "sender#tld.com" -Begin "01/04/2014" -Ende "05/05/2014"
param(
[String]$ExchangeConnector = "*",
[String]$Begin=(get-date).AddDays(-120),
[Datetime]$Ende=(get-date -uformat "%m/%d/%y %T"),
[String]$Recipient = "*",
[String]$Sender = "*",
[String]$EventID = "Receive",
[String]$Source = "SMTP"
)
Get-Exchangeserver | `
where { $_.isHubTransportServer -eq $True -or $_.isMailboxServer -eq $True } | `
$results = get-messagetrackinglog -Start $Begin -End $Ende -ResultSize Unlimited | `
where-object { `
$_.recipients -like $Recipient -and `
$_.sender -like $Sender -and `
$_.EventID -eq $EventID -and `
$_.Source -like $Source -and `
$_.connectorID -like $ExchangeConnector}
$totalKB = 0
foreach($entry in $results) {
$totalKB += $entry.totalbytes
}
$totalKB = $totalKB/1kb
$results | select Timestamp,Sender,Recipients,Messagesubject,#{label="Kilobytes";Expression={[int]($_.totalbytes/1kb)} }| ft -auto
return ("TotalKB: " + $totalKB)
}
Let me know how you get on as it's untested.

What do you think about this?
function Get-ExchangeMessagetrackinglog {
param(
[String]$ExchangeConnector = "*",
[String]$Begin=(get-date).AddDays(-120),
[Datetime]$Ende=(get-date -uformat "%m/%d/%y %T"),
[String]$Recipient = "*",
[String]$Sender = "*",
[String]$EventID = "Receive",
[String]$Source = "SMTP"
)
#Get-Exchangeserver | where { $_.isHubTransportServer -eq $True -or $_.isMailboxServer -eq $True } |
$Return= get-messagetrackinglog -Start $Begin -End $Ende -ResultSize Unlimited | where-object { $_.recipients -like $Recipient -and $_.sender -like $Sender -and $_.EventID -eq $EventID -and $_.Source -like $Source -and $_.connectorID -like $ExchangeConnector}
foreach ($returnvalue in $return) { $Returnvalue | add-member -MemberType Noteproperty -Name TotalKB -Value ([math]::round($returnvalue.totalbytes/ 1kb,2 ))
$Returnvalue | add-member -MemberType Noteproperty -Name TotalMB -Value ([math]::round($returnvalue.totalbytes/ 1MB,2 ))
}
$return
}
Get-ExchangeMessagetrackinglog -Begin "01/05/2014" -Ende "05/05/2014" | select timestamp,totalkb,sender,recipients,messagesubject | sort totalkb | ft -auto

Related

Send variables from inside Invoke-Command scriptblock back to host

The below is a script that is collecting information about SQL-jobs on remote servers.
However, I want to send the information inside the catch-block back to the host.
As the script is written now the script is printing to a logfile on each remote server.
How can I send the information back to the host?
$sqlServers = #("SERVER1","SERVER2")
$runningHost = "$env:computername"
$filePath = "C:\SQLJobInventory"
$desktopPath = [Environment]::GetFolderPath("Desktop")
$output = Invoke-Command -ComputerName $sqlServers -ArgumentList $filePath,$dateToday,$dateTodayFile -ScriptBlock{
param
(
$filePath,
$dateToday,
$dateTodayFile
)
$runningHostRemote = $env:computername
Try
{
Import-Module sqlserver -ErrorAction Stop
$instances = $runningHostRemote | Foreach-Object {Get-ChildItem -Path "SQLSERVER:\SQL\$_"} -ErrorAction Stop
}
Catch
{
Write-Output "$dateToday [ERROR] $runningHostRemote" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append
Exit
}
ForEach ($instance in $instances)
{
Try
{
$instanceName = $instance.InstanceName
Get-SqlAgentJob -ServerInstance "$runningHostRemote\$instanceName" -ErrorAction Stop |
Where-Object {$_.IsEnabled -eq "True" -and $_.LastRunDate -gt [DateTime]::Today.AddDays(-2) -and $_.OwnerLoginName -match "LKL"} |
Select-Object #{Name=‘Job name‘;Expression={$_.Name}},
#{Name=‘Description‘;Expression={$_.Description}},
#{Name=‘Instance‘;Expression={$_.Parent -Replace '[][]'}},
#{Name=‘Run outcome‘;Expression={$_.LastRunOutcome}},
#{Name=‘Run date‘;Expression={$_.LastRunDate}},
#{Name=‘Run duration‘;Expression={$_.LastRunDuration}},
#{Name=‘Job creator‘;Expression={$_.OwnerLoginName}},
#{Name=‘Runs on a schedule‘;Expression={$_.HasSchedule}},
#{Name='Schedule Type';Expression={$_.JobSchedules -join ','}}
}
Catch
{
Write-Output "$dateToday [ERROR] $runningHostRemote\$instanceName" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append
Exit
}
}
}
$output | Select-Object -Property * -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName |
Sort-Object "Job name" |
Export-Csv $filePath\SQLJobInvent$dateTodayFile.csv -NoTypeInformation -Delimiter ";" -Encoding UTF8
Write-Output "$dateToday [INFO] $filePath\Log$dateTodayFile.txt" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append
Change write-output to return
Catch
{
Return "$dateToday [ERROR] $runningHostRemote\$instanceName"
}
Return will exit the script block and pass your string back to the output variable.
I have solved it by creating my own properties of the output-variable with New-Object.
There is probably a better way to do it but this was the most convinient.
The Return-method did not work for me in this particular script.
$runningHost = "$env:computername"
$filePath = "C:\SQLJobInventory"
$lastResortPath = [Environment]::GetFolderPath("Desktop")
$dateToday = Get-Date -Format “yyMMdd HH:mm"
$dateTodayFile = Get-Date -Format “yyMMdd"
$output = Invoke-Command -ComputerName $sqlServers -ArgumentList $filePath,$dateToday,$dateTodayFile -ScriptBlock{
param
(
$filePath,
$dateToday,
$dateTodayFile
)
$runningHostRemote = $env:computername
Try
{
Import-Module sqlserver -ErrorAction Stop
$instances = $runningHostRemote | Foreach-Object {Get-ChildItem -Path "SQLSERVER:\SQL\$_"} -ErrorAction Stop
}
Catch
{
$moduleError = #{moduleError="$dateToday [ERROR] $runningHostRemote"}
New-Object -Type PSObject -Property $moduleError
Exit
}
ForEach ($instance in $instances){
Try
{
$instanceName = $instance.InstanceName
$jobSuccess = #{jobSuccess="$dateToday [INFO]"}
New-Object -Type PSObject -Property $jobSuccess
Get-SqlAgentJob -ServerInstance "$runningHostRemote\$instanceName" -ErrorAction Stop |
Where-Object {$_.IsEnabled -eq "True" -and $_.LastRunDate -gt [DateTime]::Today.AddDays(-2) -and $_.OwnerLoginName -match "LKL"} |
Select-Object #{Name=‘Job name‘;Expression={$_.Name}},
#{Name=‘Description‘;Expression={$_.Description}},
#{Name=‘Instance‘;Expression={$_.Parent -Replace '[][]'}},
#{Name=‘Run outcome‘;Expression={$_.LastRunOutcome}},
#{Name=‘Run date‘;Expression={$_.LastRunDate}},
#{Name=‘Run duration‘;Expression={$_.LastRunDuration}},
#{Name=‘Job creator‘;Expression={$_.OwnerLoginName}},
#{Name=‘Runs on a schedule‘;Expression={$_.HasSchedule}},
#{Name='Schedule Type';Expression={$_.JobSchedules -join ','}}
}
Catch
{
$jobError = #{jobError="$dateToday [ERROR] $runningHostRemote\$instanceName"}
New-Object -Type PSObject -Property $jobError
Exit
}
}
}
$output | Select-Object -ExpandProperty moduleError -ErrorAction SilentlyContinue | Out-File "$filePath\Log$dateTodayFile.txt" -Append
$output | Select-Object -ExpandProperty Jobsuccess -ErrorAction SilentlyContinue | Out-File "$filePath\Log$dateTodayFile.txt" -Append
$output | Select-Object -ExpandProperty jobError -ErrorAction SilentlyContinue | Out-File "$filePath\Log$dateTodayFile.txt" -Append
$output | Select-Object -Property * -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName |
Sort-Object "Job name" |
Export-Csv $filePath\SQLJobInvent$dateTodayFile.csv -NoTypeInformation -Delimiter ";" -Encoding UTF8
Write-Output "$dateToday [INFO] $filePath\Log$dateTodayFile.txt" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append

How can I log these Active Directory account operations to a CSV file?

I want to create a .csv file for each AD account that is disabled and moved that has the $account.Distingushed name of the object move and the $OU.Distinguished name that the object is moved from.
What would be the best way to handle this?
$OUs | Where-Object{$excludeOUS -notcontains $_.DistinguishedName } | Foreach-Object {
$params = #{}
$params = #{
SearchBase = [String]$_.DistinguishedName
SearchScope = [String]"OneLevel"
AccountInactive = $true
TimeSpan = ([timespan]$days)
Verbose = $true
}
If($users) {
$params.Add("UsersOnly",$true)
}
ElseIf($computers) {
$params.Add("ComputersOnly",$true)
}
$accounts = Search-ADAccount #params
foreach ($account in $accounts) {
$params = #{}
$params = #{
Identity = [string]$account.DistinguishedName
Verbose = $true
}
If ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "User" ) {
Disable-ADAccount #params #whatIf
$params.Add("Description",$description)
Set-ADUser #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Users,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
}
ElseIf ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "Computer") {
Disable-ADAccount #params #whatIf
$params.Add("Description",$description)
Set-ADComputer #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Computers,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
}
}
}
You can try something like below code (untested).
Set the variables for the csvPath, ouDistinguishedName and accountDistinguishedName.
You can add those vars to an object and export to csv. I used $account.Name as the csv name, but you can use something else.
$csvPath = "c:\temp"
$OUs | Where-Object { $excludeOUS -notcontains $_.DistinguishedName } | Foreach-Object {
$ouDistinguishedName = $_.DistinguishedName
$params = #{ }
$params = #{
SearchBase = [String]$_.DistinguishedName
SearchScope = [String]"OneLevel"
AccountInactive = $true
TimeSpan = ([timespan]$days)
Verbose = $true
}
If ($users) {
$params.Add("UsersOnly", $true)
}
ElseIf ($computers) {
$params.Add("ComputersOnly", $true)
}
$accounts = Search-ADAccount #params
foreach ($account in $accounts) {
$accountDistinguishedName = $account.DistinguishedName
$accountName = $account.Name
$params = #{ }
$params = #{
Identity = [string]$account.DistinguishedName
Verbose = $true
}
If ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "User" ) {
Disable-ADAccount #params #whatIf
$params.Add("Description", $description)
Set-ADUser #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Users,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
$objectProperty = #{}
$objectProperty.Add('Account',$accountDistinguishedName)
$objectProperty.Add('OU',$ouDistinguishedName)
$object = New-Object -TypeName psobject -Property $objectProperty
$object | Export-Csv "$csvPath\$accountName.csv" -NoTypeInformation
}
ElseIf ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "Computer") {
Disable-ADAccount #params #whatIf
$params.Add("Description", $description)
Set-ADComputer #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Computers,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
$objectProperty = #{}
$objectProperty.Add('Account',$accountDistinguishedName)
$objectProperty.Add('OU',$ouDistinguishedName)
$object = New-Object -TypeName psobject -Property $objectProperty
$object | Export-Csv "$csvPath\$accountName.csv" -NoTypeInformation
}
}
}
You can even export this straightly as a hashtable:
#{"Account" = $accountDistinguishedName; "OU" = $ouDistinguishedName}.GetEnumerator() | Export-Csv "$($csvpath)\$($accountname)" -NoTypeInformation
I figured it out!
$acctsCSV = #(
[pscustomobject]#{
Account = [string]$account.Name
OU = [string]$OU.DistinguishedName
}
)
$acctsCSV | Export-Csv -Path $filePath -NoTypeInformation

How to output from a Powershell hashtable to a output file

I am trying to get the .NetFramwork version from all the windows servers. I am using powershell script. I can get the output displayed but unable to get the output from the hashtable to a output file. Also how would I get rid of the "..." from VersionDetails : {1.0.3705, 1.1.4322, 2.0.50727, 3.0...} and show the full content.
Any help will be greatly appreciated
here is the code I am using:
$username = "username"
$password = "Password"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
$query = "select name from win32_directory where name like 'c:\\windows\\microsoft.net\\framework\\v%'"
$ComputerNames = Get-Content "d:\Scripts\serverList.txt"
foreach ($ComputerName in $ComputerNames)
{
write-host "ComputerName = $ComputerName"
$ComputerName | ForEach-Object {
$res = Get-WmiObject -query $query -Credential $cred -ComputerName $ComputerName | ForEach-Object {
Split-Path $_.name -Leaf } | # returns directories
Where-Object { $_ -like 'v*' } | # only include those that start with v
ForEach-Object { [system.version]( $_ -replace "^v" ) }
# remove "v" from the string and convert to version object
# Create hashtable with computername and version details
$prop = #{
ComputerName = $ComputerName
#V1_Present = &{ if ( $res | Where-Object { $_.Major -eq 1 -and $_.Minor -eq 0 } ) { $true } }
#V1_1Present = &{ if ( $res | Where-Object { $_.Major -eq 1 -and $_.Minor -eq 1 } ) { $true } }
V2_Present = &{ if ( $res | Where-Object { $_.Major -eq 2 -and $_.Minor -eq 0 } ) { $true } }
V3_Present = &{ if ( $res | Where-Object { $_.Major -eq 3 -and $_.Minor -eq 0 } ) { $true } }
V3_5Present = &{ if ( $res | Where-Object { $_.Major -eq 3 -and $_.Minor -eq 5 } ) { $true } }
V4_Present = &{ if ( $res | Where-Object { $_.Major -eq 4 -and $_.Minor -eq 0 } ) { $true } }
VersionDetails = $res
}
# Create and output PSobject using hashtable
New-Object PSObject -Property $prop
}
=========================================================
Output dispalys
PS D:\Scripts> .\GetDotNetFrameworkver.ps1
in for loop ComputerName = XXXXXXX
V4_Present : True
V3_5Present : True
V2_Present : True
V3_Present : True
ComputerName : XXXXX
VersionDetails : {1.0.3705, 1.1.4322, 2.0.50727, 3.0...}
Based on the answer of link there is a "simpler" (and faster) solution to fetch the versions.
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse | Get-ItemProperty -name Version,Release -ErrorAction Ignore | Where { $_.PSChildName -match '^(?!S)\p{L}'} | Select PSChildName, Version, Release
If you want to get the versions of different remote machines you can use PowerShell remoting. Be aware that you've to enable PS remoting .If your OS version is WIN10/WIN2012R2 it is enabled per default. If you're using an older OS you've to call Enable-PSRemoting on the remote machine. See this link for details.
Example:
$result = Invoke-Command -ComputerName computer1.domain, computer1.domain -Credential (Get-Credential ) -ScriptBlock {
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse | Get-ItemProperty -name Version,Release -ErrorAction Ignore | Where { $_.PSChildName -match '^(?!S)\p{L}'} | Select PSChildName, Version, Release
}
$hash = $result | group PSComputerName -AsHashTable # Group the .Net versions by computername
$hash.'computer1.domain' # Print all .Net version of computer1
$hash.'computer1.domain'.Version # Only print the version
Hope that helps.

Issues with powershell invoke-command, Unexpected token '-ArgumentList' in expression or statement

I am quite new to powershell. I am trying to remote to PCs in a csv file and extract the status of a registry key. However I get the error
"Unexpected token '-ArgumentList' in expression or statement." when I try to execute. And I am not pretty sure on the syntax of the Invoke-Command, can one of your pls verify if it is correct? Appreciate your help.
So basically, what I intend to do is, get computer names, specify an output path which I will be then using inside the invoke command. Testing the online status of the PC, checking the required registry value and writing it to the file.
$computers = Get-Content "C:\Temp\AutoSug\Computers.txt"
$output_path = "C:\Temp\AutoSug\output.csv"
foreach($computer in $computers)
{
Test-Connection -computername $computer -Quiet
If (Test-Connection $computer -count 1 -quiet)
{
Invoke-Command -computer $computer -ScriptBlock
{
param(
$output_path
)
$hostname = (Get-CIMInstance CIM_ComputerSystem).Name
$objExcel = New-Object -ComObject Excel.Application
if ($objExcel.Version -eq "15.0")
{
$HKEY_USERS = Get-ChildItem REGISTRY::HKEY_USERS | where-object { ($_.Name -like "*S-1-5-21*") -and ($_.Name -notlike "*_Classes") }
$Users = #()
$value = #()
foreach ($User in $HKEY_USERS)
{
$PROFILESID = Get-ChildItem REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.name -like "*" + $USER.PSChildName + "*" }
$SID = $PROFILESID.PSChildName
foreach ($value in $SID)
{
$key = Get-Item REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\15.0\Outlook\Preferences -ErrorAction SilentlyContinue
$gold = $key.property
if($gold -like 'ShowAutoSug')
{
$grail = (Get-ItemProperty REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\15.0\Outlook\Preferences).ShowAutoSug
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname, $objUser, $value , $grail | Add-Content $output_path
}
else
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname,$objUser, $value , "The Auto Complete is not disabled" | Add-Content $output_path
}
}
}
}
if ($objExcel.Version -eq "14.0")
{
$HKEY_USERS = Get-ChildItem REGISTRY::HKEY_USERS | where-object { ($_.Name -like "*S-1-5-21*") -and ($_.Name -notlike "*_Classes") }
$Users = #()
$value = #()
foreach ($User in $HKEY_USERS)
{
$PROFILESID = Get-ChildItem REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.name -like "*" + $USER.PSChildName + "*" }
$SID = $PROFILESID.PSChildName
foreach ($value in $SID)
{
$key = Get-Item REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\14.0\Outlook\Preferences -ErrorAction SilentlyContinue
$gold = $key.property
if($gold -like 'ShowAutoSug')
{
$grail = (Get-ItemProperty REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\14.0\Outlook\Preferences).ShowAutoSug
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname, $objUser, $value , $grail | Add-Content -path $output_path
}
else
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname,$objUser, $value , "The Auto Complete is not disabled" | Add-Content $output_path
}
}
}
}
if ($objExcel.Version -eq "12.0")
{
$HKEY_USERS = Get-ChildItem REGISTRY::HKEY_USERS | where-object { ($_.Name -like "*S-1-5-21*") -and ($_.Name -notlike "*_Classes") }
$Users = #()
$value = #()
foreach ($User in $HKEY_USERS)
{
$PROFILESID = Get-ChildItem REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.name -like "*" + $USER.PSChildName + "*" }
$SID = $PROFILESID.PSChildName
foreach ($value in $SID)
{
$key = Get-Item REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\12.0\Outlook\Preferences -ErrorAction SilentlyContinue
$gold = $key.property
if($gold -like 'ShowAutoSug')
{
$grail = (Get-ItemProperty REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\12.0\Outlook\Preferences).ShowAutoSug
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname, $objUser, $value , $grail | Add-Content $output_path
}
else
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname,$objUser, $value , "The Auto Complete is not disabled" |Add-Content $output_path
}
}
}
}
} -ArgumentList $output_path
}
else
{
$status = 'Offline'
$computer , $status | Add-Content $output_path
}
}
To fix your error, simply cut -ArgumentList $output_path and put it before -ScriptBlock like:
Invoke-Command -computer $computer -ArgumentList $output_path -ScriptBlock ....

Powershell script from task scheduler unable to work as intended

I have a script file that when ran from within ISE or from the powershell window it works fine. But when ran trough the task scheduler with "runas" the same account it only outputs half the data.
After some troubleshooting i have concluded that the part of the code that is not working is:
Get-ADOrganizationalUnit -SearchBase $OU -Filter {objectclass -eq "organizationalunit"} -SearchScope onelevel -Properties description |
% {
$mailbox = #( get-user -OrganizationalUnit $_.distinguishedName -resultsize unlimited |
? { $_.title -ne "xxx" -and $_.RecipientType -eq "usermailbox" -and $_.RecipientTypeDetails -ne "RoomMailbox" } )
if ($mailbox.count -gt 0) {
$name = $_.name
$mail_customer = $body
$mail_customer += "<h3>" + $name + "</h3>"
$mail_customer += $mailbox | get-MailboxStatistics |
select displayname, lastlogontime, #{ label = "Mailbox Size(MB)"; expression = {
if ($_.totalitemsize.value.toMB() -gt 25600) { "!!!" + $_.TotalItemSize.Value.ToMB() }
else { $_.TotalItemSize.Value.ToMB() }
} } | Sort-Object displayname | ConvertTo-Html -Fragment | Out-String
$count += $mailbox.count
$stattable += #{$name = $mailbox.count}
$mail_customer = $mail_customer | ForEach-Object { $_ -replace '!!!', '<font color="#FF0000">' }
if ( $_.description -ne $null ) {
$mailaddresses = $_.description.split(",")
Send-MailMessage `
-SmtpServer $SMTPserver `
-Encoding $encoding `
-From "$company <noreply#$companylower.se>" `
-To $mailaddresses `
-Subject "$company report - $name - $date" `
-BAH `
-Body $mail_customer
}
$mail += $mail_customer
$mailaddresses = "";
}
}
I get the email but it does not include the information that these lines should output, any ideas?
Script is called like this: powershell -file c:\temp\scriptname.ps1
This is a classic case of not running something elevated. Nothing in the code was wrong.
In Task Scheduler, make sure "Run with highest privileges" is ticked in for the task or it will not work.