首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否从vmware.log文件的最后一行检索数据?

是否从vmware.log文件的最后一行检索数据?
EN

Stack Overflow用户
提问于 2017-07-06 02:46:12
回答 2查看 1K关注 0票数 0

我目前有一个脚本,可以在vCenter中的VM数据存储中检索.vmx的最后修改日期。我需要进行更改,以使用并显示vmware.log文件(位于与.vmx相同的数据存储中)中的最后日期

我不确定如何获取该行并将其转换为XX/XX/XXXX格式。在日志文件中,它显示为例如12月23日10。如果这是不可能的,不用担心。我只需要提取日志文件中的最后一行并将其导出到.csv文件。下面是我当前的代码:

代码语言:javascript
复制
add-pssnapin VMware.VimAutomation.Core

# ---------- Only modify the fields in this area -------------
$vCenter = 'qlab-copsmgr'                  #name of the vCenter 
$dataCenter = 'Fly-away Kit'               #name of the DataCenter 
$outputFile = $vCenter + '-LastDateUsed.csv'             #desired output file name

# ---------- No modification is needed in the below code. Do not edit   -------------
$columnName = "Name,DataStore,Date Last Used" | Out-File .\$OutputFile -Encoding ascii
Connect-VIServer $vCenter -WarningAction SilentlyContinue
$vmList = Get-VM | where { $_.PowerState -eq “PoweredOff”} | select Name
$vmList = $vmList -replace 'Name : ', '' -replace '@{Name=', '' -replace '}', ''

ForEach ($VM in $vmList)
{
    # Get configuration and path to vmx file
    $VMconfig = Get-VM $VM | Get-View | select config
    $VMXpath = $VMconfig.config.files.VMpathName

    # Remove and/or replace unwanted strings
    $VMXpath = $VMXpath -replace '\[','' -replace '\] ','\' -replace '@{Filename=','/' -replace '}','' -replace '/','\'

    # List the vmx file in the datastore
    $VMXinfo = ls vmstores:\$VCenter@443\$DataCenter\$VMXpath | Where {$_.LastWriteTime} | select -first 1 | select FolderPath, LastWriteTime

    # Remove and/or replace unwanted strings
    $VMXinfo = $VMXinfo -replace 'DatastoreFullPath=', '' -replace '@{', '' -replace '}', '' -replace ';', ',' -replace 'LastWriteTime=', ''

    # Output vmx information to .csv file
    $output = $VM + ', ' + $VMXinfo
    $output
    echo $output >> $OutputFile
}
EN

回答 2

Stack Overflow用户

发布于 2018-02-27 00:00:14

我还需要从vmware.log文件中提取最后一个事件,以便回溯没有vCenter事件历史记录的VM的断电时间。我查看了文件时间戳,但发现一些虚拟机进程和可能的备份解决方案可能会使它们变得无用。

我尝试就地读取文件,但遇到了PSDrive类型不支持Get-Content就地的问题。因此,无论对我的解决方案是好是坏,我都是从LucD的一个脚本开始的-从http://www.lucd.info/2011/02/27/virtual-machine-logging/获取日志脚本,该脚本提取一个虚拟机vmware.log文件并将其复制到本地存储。然后我对其进行了修改,将vmware.log文件复制到本地临时文件夹,在删除文件之前读取文件中的最后一行,并将日志的最后一行作为PS对象返回。

请注意,这很慢,我确信我对LucD脚本的修改并不优雅,但它确实有效,我希望它能帮助某些人。

注意:这会将日志中的时间值转换为PS date对象,方法是将文件中的字符串timestamp转换为Get-Date。我已经了解到,对于非美国日期格式,这不能像预期的那样工作。对于那些在美国以外的人,您可能想要研究一下这一点,或者只传递日志中的原始时间戳字符串,而不是转换它。

代码语言:javascript
复制
#Examples:
#$lastEventTime = (Get-VM -Name "SomeVM" | Get-VMLogLastEvent).EventTime
#$lastEventTime = Get-VMLogLastEvent -VM "SomeVM" -Path "C:\alternatetemp\"

function Get-VMLogLastEvent{
    param(
    [parameter(Mandatory=$true,ValueFromPipeline=$true)][PSObject[]]$VM,
    [string]$Path=$env:TEMP
    )

    process{   
        $report = @()

        foreach($obj in $VM){
            if($obj.GetType().Name -eq "string"){
                $obj = Get-VM -Name $obj
            }
            $logpath = ($obj.ExtensionData.LayoutEx.File | ?{$_.Name -like "*/vmware.log"}).Name
            $dsName = $logPath.Split(']')[0].Trim('[')
            $vmPath = $logPath.Split(']')[1].Trim(' ')
            $ds = Get-Datastore -Name $dsName
            $drvName = "MyDS" + (Get-Random)
            $localLog = $Path + "\" + $obj.Name + ".vmware.log"
            New-PSDrive -Location $ds -Name $drvName -PSProvider VimDatastore -Root '\' | Out-Null
            Copy-DatastoreItem -Item ($drvName + ":" + $vmPath) -Destination $localLog -Force:$true
            Remove-PSDrive -Name $drvName -Confirm:$false

            $lastEvent = Get-Content -Path $localLog -Tail 1
            Remove-Item -Path $localLog -Confirm:$false

            $row = "" | Select VM, EventType, Event, EventTime
            $row.VM = $obj.Name
            ($row.EventTime, $row.EventType, $row.Event) = $lastEvent.Split("|")
            $row.EventTime = $row.EventTime | Get-Date
            $report += $row
         }
         $report        
    }
} 

这应该涵盖了您的请求,但为了进一步阐述我为什么需要详细信息,字里行间的阅读可能也会对您有所帮助,我将继续。

我继承了数以百计的遗留虚拟机,这些虚拟机从过去的各种收购和剥离中断电,其中许多虚拟机在vCenter实例之间移动,丢失了所有事件日志详细信息。当我在一个数据中心开始清理工作时,我有超过60TB的虚拟机断电。由于这些虚拟机的遗留性质,也没有关于谁拥有这些旧虚拟机或了解这些旧虚拟机的详细信息。

为此,我破解了另一个脚本,也是从LucD找到的:https://communities.vmware.com/thread/540397

这将包含所有关闭的虚拟机,尝试通过vCenter事件历史记录确定关闭电源的时间。我将其修改为回退到上面的Get-VMLogLastEvent函数,以便在事件日志详细信息不可用时获取VM的最终断电时间。

错误捕获可能会得到改进-这将在由于某种原因没有vmware.log文件的虚拟机上发生错误。但很快和肮脏,我发现这是工作,并提供了我需要的超过90%的细节。

同样,这依赖于上面的函数,至少对我来说,通过传递空值会导致错误失败。在尝试复制之前,可以通过添加对vmware.log是否存在的检查来消除错误,尽管由于PSDrive接口到数据存储的速度很慢,这会增加执行中的延迟。

代码语言:javascript
复制
$Report = @()  

$VMs = Get-VM | Where {$_.PowerState -eq "PoweredOff"}  
$Datastores = Get-Datastore | Select Name, Id  
$PowerOffEvents = Get-VIEvent -Entity $VMs -MaxSamples ([int]::MaxValue) | where {$_ -is [VMware.Vim.VmPoweredOffEvent]} | Group-Object -Property {$_.Vm.Name}  

foreach ($VM in $VMs) {  
    $lastPO = ($PowerOffEvents | Where { $_.Group[0].Vm.Vm -eq $VM.Id }).Group | Sort-Object -Property CreatedTime -Descending | Select -First 1 
    $lastLogTime = "";

    # If no event log detail, revert to vmware.log last entry which takes more time...
    if (($lastPO.PoweredOffTime -eq "") -or ($lastPO.PoweredOffTime -eq $null)){
        $lastLogTime = (Get-VMLogLastEvent -VM $VM).EventTime
    }

    $row = "" | select VMName,Powerstate,OS,Host,Cluster,Datastore,NumCPU,MemMb,DiskGb,PoweredOffTime,PoweredOffBy,LastLogTime
    $row.VMName = $vm.Name  
    $row.Powerstate = $vm.Powerstate  
    $row.OS = $vm.Guest.OSFullName  
    $row.Host = $vm.VMHost.name  
    $row.Cluster = $vm.VMHost.Parent.Name  
    $row.Datastore = $Datastores | Where{$_.Id -eq ($vm.DatastoreIdList | select -First 1)} | Select -ExpandProperty Name  
    $row.NumCPU = $vm.NumCPU  
    $row.MemMb = $vm.MemoryMB  
    $row.DiskGb = Get-HardDisk -VM $vm | Measure-Object -Property CapacityGB -Sum | select -ExpandProperty Sum  
    $row.PoweredOffTime = $lastPO.CreatedTime  
    $row.PoweredOffBy   = $lastPO.UserName
    $row.LastLogTime = $lastLogTime
    $report += $row  
}  

# Output to screen  
$report | Sort Cluster, Host, VMName | Select VMName, Cluster, Host, NumCPU, MemMb, @{N='DiskGb';E={[math]::Round($_.DiskGb,2)}}, PoweredOffTime, PoweredOffBy | ft -a  

# Output to CSV - change path/filename as appropriate  
$report | Sort Cluster, Host, VMName | Export-Csv -Path "output\Powered_Off_VMs_Report.csv" -NoTypeInformation -UseCulture  

干杯!我祈祷这能补偿我用过的一些因果报应。

Meyeaard

票数 1
EN

Stack Overflow用户

发布于 2017-07-06 14:48:30

我已经创建了一个逐行检查的脚本,如果找到字符串,则将其更改为所需的格式

代码语言:javascript
复制
#example input you can use get-content PATH to txt or any file and assign it to $lines variable
$lines = @"
ernfoewnfnsf
ernfoewnfnsf
Dec 23 10 sgdsgdfgsdadasd
"@ -split "\r\n"

#checks line by line and if find anything that maches start of the line, one Big letter two small, space, two digits, space, two digits, space 
$lines | ForEach-Object{

    if ($_ -match "^[A-Z][a-z]{2}\s\d{2}\s\d{2}\s")
    {
        $match = [convert]::ToDateTime($matches[0])
        $_ -replace $matches[0], "$($match.ToShortDateString()) " | out-file { PATH } -APPEND
    }
    else
    {
        $_ | out-file { PATH } -APPEND
    }
}

只需使用filenamePAth更改{PATH},这应该适用于您

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44933835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档