【运维】PowerShell编程 目录文件相关方法的封装与案例详解

简介: 本文实现一个目录管理类,归纳了 Powershell 中常用的文件路径方法。这些方法可以迅速方便的用于 Powershell 编写大型运维脚本中。以简单使用为目的封装常用目录文件操作。完成源代码在作者的github上可以找到。

PowerShell 目录文件管理


目录文件相关方法的封装与案例详解

李俊才 的个人博客https://blog.csdn.net/qq_28550263?type=blog

已入驻阿里云

邮箱 :291148484@163.com
本文地址
- https://developer.aliyun.com/article/
- https://blog.csdn.net/qq_28550263/article/details/124378032

本文通过以一个 Path 类,归纳了 Powershell 中常用的文件路径方法。这些方法可以迅速方便的用于 Powershell 编写大型运维脚本中。


目 录


1. 获取绝对路径

2. 文件名

3. 获取盘符

4. 当前系统临时目录

5. 上级路径

6. 文件或者目录是否实际存在

7. 获取相对路径

8. 获取目录的当前子项目

9. 递归获取目录的所有子孙项目

10. 在指定目录下筛选文件

11. 在指定目录下筛选目录

12. 获取文件或者目录的修改时间

13. 判断指定路径是否实际是一个文件夹

14. 判断指定路径是否实际是一个文件

15. 判断文件时间是否早于某个值

16. 判断目录是否为空

17. 判断某个路径值是否为绝对路径

18. 获取目录的属性描述符

19. 判 断是否包含某个属性描述符

20. 计算文件或目录的大小

21. 连结多个路径

22. 拆分路径

23. 创建目录

24. Path 环境变量相关方法

25. 删除路径对应的项目

附录1: Path类代码

附录2: 脚本位置


1. 获取绝对路径

static [string]abspath([string]$path){
    <#
    Return absolute path
    Params
    ======
    - $path [string] Path of file.
    #>
    return Resolve-Path -Path $path; 
}

如图:

2. 文件名

static [string]basename([string]$path){
    <#
    Returns the file name from the absolute path value represented by a string.
    Params
    ======
    - $path [string] The absolute path of the file.
    - $extension [bool] Whether to remove the extension.
    #>
    return  [System.IO.Path]::GetFileName($path)
}
static [string]basename([string]$path,[bool]$extension=$True){
    if($extension){
        return  [System.IO.Path]::GetFileName($path)
    }
    else{
        return [System.IO.Path]::GetFileNameWithoutExtension($path)
    }
}

如图:

3. 获取盘符

static [string]rootname([string]$path){
    <# Return root directory information #>
    return [System.IO.Path]::GetPathRoot($path)
}

【例如】:

4. 当前系统临时目录

static [string]get_temp_path(){
    <# Returns the path of the current system temporary directory. #>
    return [System.IO.Path]::GetTempPath()
}

【例如】:

5. 上级路径

5.1 获取文件所在目录名(上级目录名)

static [string]get_dirname([string]$path){
    <#
    Returns the name of the folder where the file is located.
    Params
    ======
    - $path [string] Represents the absolute path of a file or folder.
    #>
    return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
}
static [string]get_dirname([string]$path, [bool]$absolute=$True){
    if($absolute){
        return [System.IO.Path]::GetDirectoryName($path)
    }
    else{
        return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
    }
}

【例如】:

备注:

这里图片调用的是之前的版本的方法名,现在已经改名为 get_dirname ,只要替换方法名效果一样,只是没有重新截图了。

5.2 获取文件所在目录名(上级绝对路径)

static [string]get_dirpath([string]$path){
    <#
    Returns the absolute path of the parent folder.
    Params
    ======
    - $path [string] Represents the absolute path of a file or folder.
    #>
    return [System.IO.Path]::GetDirectoryName($path)
}

6. 判断文件或者目录是否实际存在

static [bool] exists([string]$path){
    <#
    Determine whether the specified file or directory exists.
    Params
    ======
    - $path [string] The path value represented by a string.
    Returns
    =======
    - $True  exist.
    - $False non-existent.
    #>
    return Test-Path -Path $path
}

例如:

7. 获取相对路径

static [string]relpath([string]$relativeTo, [string]$path){
    <#
    Returns the relative path from one path to another.
    Params
    ======
    - $relativeTo [string] The source path relative to the result. This path is always treated as a directory.
    - $path [string] Target path.
    Returns
    =======
    [string] Relative path, or path if the paths do not share the same root.
    Exceptions
    ==========
    - [ArgumentNullException] The value of $relativeTo or $path is null。
    - [ArgumentException] $relativeTo or $path is actually null.
    #>
    return [System.IO.Path]::GetRelativePath($relativeTo, $path)
}

【例如】:

8. 获取目录的当前子项目

static [string[]] get_items([string]$path){
    <#
    Get all subprojects in the specified directory. 
    Params
    ======
    - $path [string] The path value represented by a string.
    - $sift [string] Optional, used to indicate the filtered content.
        * When the parameter value is' file', only the absolute path of 
        the files in it will be returned.
        * When the parameter value is' folder', the absolute path of the 
        directory (folder) in it is returned.
    Notes
    =====
        This method only gets the current level of subdirectories, while 
        the folders containing subdirectories will not be traversed.
        If you need to recursively obtain all descendants directories, 
        you should consider using `get_descendants()` method instead.
    #>
    $item_obj = Get-ChildItem $path |  Sort-Object
    $ary = [ArrayList]::new()
    foreach ($item in $item_obj){
        $ary.Add($item.ToString())
    }
    return $ary
}
static [string[]] get_items([string]$path, [string]$sift){
    if($sift -eq 'file'){
        $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
        $ary = [ArrayList]::new()
        foreach ($item in $files){
            $ary.Add($item.ToString())
        }
        return $ary
    }elseif ($sift -eq 'folder') {
        $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
        $ary = [ArrayList]::new()
        foreach ($item in $folders){
            $ary.Add($item.ToString())
        }
        return $ary
    }else{
        $item_obj = Get-ChildItem $path |  Sort-Object
        $ary = [ArrayList]::new()
        foreach ($item in $item_obj){
            $ary.Add($item.ToString())
        }
        return $ary
    }
}

【例如】:

其中:

  • 由于该目录中没有直接子项目为文件,因此当指定第二个参数为file时,结果为空;
  • 指定第二个参数为folder和不指定第二个参数的效果完全一致。

9. 递归获取目录的所有子孙项目

static [string[]] get_descendants([string]$path){
    <#
    Get all items in the specified directory, and recursively traverse all descendant folders.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $sift [string] Optional, used to indicate the filtered content.
        * When the parameter value is' file', only the absolute path of the files in it will be returned.
        * When the parameter value is' folder', the absolute path of the directory (folder) in it is returned.
    #>
    $ary = [ArrayList]::new();
    $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
    foreach ($item in $item_obj){
        if([Path]::is_dirname($item)){
            $sub_ary = [Path]::get_descendants($item);
            $ary.AddRange($sub_ary);
        }
        else{
            $ary.Add($item);
        }
    }
    return $ary
}
static [string[]] get_descendants([string]$path, [string]$sift){
    $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
    $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
    $ary = [ArrayList]::new()
    # only file
    if($sift -eq 'file'){
        if($null -ne $files){
            foreach ($file in $files){
                $ary.Add($file)
            }
        }
        foreach ($item in $folders){
            $ary.AddRange([Path]::get_descendants($item,'file'))
        }
    }
    # only dir
    elseif ($sift -eq 'folder') {
        if($null -ne $folders){
            foreach ($item in $folders){
                $ary.Add($item);
                $ary.AddRange([Path]::get_descendants($item,'folder'))
            }
        }
    }
    # all
    else{
        $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
        foreach ($item in $item_obj){
            if([Path]::is_dirname($item)){
                $sub_ary = [Path]::get_descendants($item);
                $ary.AddRange($sub_ary);
            }
            else{
                $ary.Add($item);
            }
        }
    }
    return $ary
}

【例如】:

方法 get_descendants 与方法 get_items 的区别在于, get_descendants的查找范围不限于其自身,还包括其所有的子孙目录。

10. 在指定目录下筛选文件

static [string[]]filter_files([string]$path, [string]$sub_string){
    <#
    Filter the files containing the specified string from the specified directory.
    Params
    ======
    - $path [string] 
    - $sub_string [string] 
    - $recursion [bool] Recursively search all descendant directories, defaulf $False
    #>
    $ary = [ArrayList]::new();
    foreach ($item in [Path]::get_items($path,'file')) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}
static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){
    $ary = [ArrayList]::new();
    if($recursion){
        $all = [Path]::get_descendants($path,'file')
    }else{
        $all = [Path]::get_items($path,'file')
    }
    foreach ($item in $all) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}

【例如】:

11. 在指定目录下筛选目录

static [string[]]filter_dirs([string]$path, [string]$sub_string){
    $ary = [ArrayList]::new();
    foreach ($item in [Path]::get_items($path,'folder')) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}
static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){
    $ary = [ArrayList]::new();
    if($recursion){
        $all = [Path]::get_descendants($path,'folder')
    }else{
        $all = [Path]::get_items($path,'folder')
    }
    foreach ($item in $all) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}

【例如】:

12. 获取文件或者目录的修改时间

static [System.DateTime]get_modify_time([string]$path){
    <#
    Returns the last modification time of a file or directory.
    Params
    ======
    - $path [string] The path value represented by a string.
    #>
    return [System.IO.DirectoryInfo]::new($path).LastWriteTime
}

【例如】:

13. 判断指定路径是否实际是一个文件夹

static [bool]is_dirname([string]$path){
    <#
    Specifies whether the path represents a folder.
    Params
    ======
    - $path [string] The path value represented by a string.
    Returns
    =======
        - $True  If the specified path represents a folder
        - $False Versa
    Notes
    =====
        In most cases, you can also use the command: 
        `Test-Path -Path $path -PathType leaf `, 
        However, using the `Test-Path` command can't deal with 
        the case that the file name contains "[" as the powershell 
        compiler will throw back an error in this case.
    #>
    return [Path]::has_attributes($path,"Directory")
}

【例如】:

14. 判断指定路径是否实际是一个文件

static [bool]is_filename([string]$path){
    <#
    Returns whether the specified path value represents a file.
    Params
    ======
    - $path The path value represented by a string.
    Notes
    =====
        In most cases, you can also use the command: 
        `Test-Path -Path $path -PathType leaf `, 
        However, using the `Test-Path` command can't deal with 
        the case that the file name contains "[" as the powershell 
        compiler will throw back an error in this case.
    #>
    return -not [Path]::has_attributes($path,"Directory")
}

【例如】:

15. 判断文件是否比指定日期新

static [bool]is_newer_than($path, $time){
    <#
    Test whether the time of a file is before the specified date.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $time A point-in-time string, such as "July 13, 2009"
    Returns
    =======
    - $True  If the modification time of the specified file is newer than this point in time;
    - $False Versa。
    #>
    return Test-Path -Path $path -NewerThan $time
}

该方法仅适用于文件系统驱动器。

【例如】:

16. 判断目录是否为空

static [bool]is_empty([string]$path){
    <#
    The folder is not empty, or the specified path is a file.
    Params
    ======
    - $path [string] The path value represented by a string.
    Retuens
    =======
    - $True  Folder is empty.
    - $False The folder is not empty, or the specified path is a file.
    #>
    if([Path]::is_dirname($path)){
        if((Get-ChildItem $path).count -eq 0){
            return $True
        }
        else{
            return $False
        }
    }
    else{
        write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. "
        return $False
    }
}

【例如】:

17. 判断某个路径值是否为绝对路径

static [bool]is_abs([string]$path){
    <# 
    Determine whether the path value represents an absolute path.
    Params
    ======
    - $path [string] The path value represented by a string.
    Retuens
    =======
    - $True  Is an absolute path.
    - $False Versa.
    #>
    return Split-Path -Path $path -IsAbsolute
}

【例如】:

18. 获取目录的属性描述符

static [string[]]get_attributes([string]$path){
    <#
    Gets the operator of attribute description of the directory.
    #>
    return [System.IO.File]::GetAttributes($path).ToString().Split(", ")
}

【例如】:

【又如】:

19. 判断是否包含某个属性描述符

static [bool]has_attributes([string]$path, [string]$attributes){
    <#
    Returns whether the file or directory contains an attribute descriptor.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $attributes [string] Represents an attribute descriptor of a directory. 
    Retuens
    =======
    - $True  Includes.
    - $False Not includes.
    #>
    return [Path]::get_attributes($path).Contains($attributes)
}

【其中】:

$attributes 的值可以是:

描述
Archive 此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。
Compressed 此文件是压缩文件。
Device 留待将来使用。
Directory 此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。
Encrypted 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。
Hidden 文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。
IntegrityStream 文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。
Normal 该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。
NoScrubData 文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。
NotContentIndexed 将不会通过操作系统的内容索引服务来索引此文件。
Offline 此文件处于脱机状态, 文件数据不能立即供使用。
ReadOnly 文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。
ReparsePoint 文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。
SparseFile 此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。
System 此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。
Temporary 文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。

【例如】:

可以知道,该文件是一个具有 Hidden的文件(隐藏文件)。

20. 计算文件或目录的大小

static [int64]$counter;
static [int64]get_size([string]$path){
    <#
    Returns the file size, or an error if the file does not exist.
    Params
    ======
    - $path [string] The path value represented by a string.
    #>
    [Path]::counter = -1;
    return [Path]::get_size($path,[Path]::counter)
}
static [int64]get_size([string]$path,[string]$ParentId){
    $count_size = 0;
    $file_infos = Get-ChildItem $path;
    # If it is a file, directly return the file size.
    if($file_infos.Attribute -eq 'Archive'){
        write-host $path+" is a file."
        $count_size = $count_size + $file_infos.Length;
    }
    # If it is a directory, the total size is calculated recursively.
    else{
        $count = $file_infos.Count;
        for ($i = 0; $i -lt $file_infos.Count; $i++) {
            $child = $file_infos[$i];
            [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately.
            $ID = [Path]::counter;
            # If it is a file, the size is accumulated.
            if([Path]::is_filename($child)){
                $count_size =  $count_size + $child.Length;
            }
            # If it is a directory, continue to recursively accumulate the size.
            else{
                $count_size =  $count_size + [Path]::get_size($child,$ID)
            }
            # 进度条显示
            $percent = $i / $count;  # 以子条目计算百分比
            if($ParentId -eq -1){
                Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
            }else{
                Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
            }
        }
    }
    return $count_size
}

【例如】:

21. 连结路径

static [string]join($path, $childpath){
    <# 
    Connect the directory and file name into a path.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $childpath [string] childpath path value represented by a string.
    #>
    return Join-Path -Path $path -ChildPath $childpath
}

【例如】:

22. 拆分路径

static [string[]]split([string]$path){
    <#
    Divide the path into two parts: dirname and basename.
    Params
    ======
    - path [string] The path value represented by a string.
    Returns
    =======
    - $dirname   The absolute path of the folder.
    - $basename  Subfile or subdirectory name
    #>
    $dirname = Split-Path -Path $path -Leaf;
    $basename = Split-Path -Path $path;
    return $dirname,$basename
}

【例如】:

23. 创建目录

static [void]make($path){
    <#
    Create a series of folders according to the given path.
    Params
    ======
    - path [string] The path value represented by a string.
    #>
    New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" 
}

【例如】:

其中

  • 如果目录完全存在,则会提示错误 "An item with the specified name XXX already exists",例如两次重复创建:
  • 如果所创建的目录的祖先文件夹都不存在,则会逐个创建祖先文件夹。

24. Path 环境变量相关方法

static [string[]]get_enviroment(){
    return [Environment]::GetEnvironmentVariable('Path', 'Machine')
}
static [void]set_enviroment($path){
    [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
}
static [void]set_enviroment($path,$env_var_target){
    if($env_var_target -eq 'Machine'){
        [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
    }
    elseif($env_var_target -eq 'User'){
        [Environment]::SetEnvironmentVariable('Path', $path,'User')
    }
    else{
        write-host -ForegroundColor Red "ValueError: The value of variable  `"`$env_var_target`" can only be one of 'Machine' or 'User'." 
    }   
}

【例如】:


         

25. 删除路径对应的项目

static [void] delete([string]$path){
    <#
    Delete the file or directory corresponding to the specified path.
    Params
    ======
    - path [string] The path value represented by a string.
    #>
    Remove-Item $path;
}

【例如】:


         

附录: Path类代码

<#
@Auth: Jack Lee;
@Email: 291148484@163.com;
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#>
using namespace System;
using namespace System.Collections;
using namespace System.Collections.Generic;
class Path{
    static [string]abspath([string]$path){
        <#
        Return absolute path
        Params
        ======
        - $path [string] Path of file.
        #>
        return Resolve-Path -Path $path; 
    }
    static [string]basename([string]$path){
        <#
        Returns the file name from the absolute path value represented by a string.
        Params
        ======
        - $path [string] The absolute path of the file.
        - $extension [bool] Whether to remove the extension.
        #>
        return  [System.IO.Path]::GetFileName($path)
    }
    static [string]basename([string]$path,[bool]$extension=$True){
        if($extension){
            return  [System.IO.Path]::GetFileName($path)
        }
        else{
            return [System.IO.Path]::GetFileNameWithoutExtension($path)
        }
    }
    static [string]rootname([string]$path){
        <# Return root directory information #>
        return [System.IO.Path]::GetPathRoot($path)
    }
    static [string]get_temp_path(){
        <# Returns the path of the current system temporary directory. #>
        return [System.IO.Path]::GetTempPath()
    }
    static [string]get_dirpath([string]$path){
        <#
        Returns the absolute path of the parent folder.
        Params
        ======
        - $path [string] Represents the absolute path of a file.
        #>
      return [System.IO.Path]::GetDirectoryName($path)
  }
    static [string]get_dirname([string]$path){
        <#
        Returns the name of the folder where the file or subfolder is located.
        Params
        ======
        - $path [string] Represents the absolute path of a file.
        #>
        return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
    }
    static [string]get_dirname([string]$path, [bool]$absolute=$True){
        if($absolute){
            return [System.IO.Path]::GetDirectoryName($path)
        }
        else{
            return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
        }
    }
    static [bool] exists([string]$path){
        <#
        Determine whether the specified file or directory exists.
        Params
        ======
        - $path [string] The path value represented by a string.
        Returns
        =======
        - $True  exist.
        - $False non-existent.
        #>
        return Test-Path -Path $path
    }
    static [string]relpath([string]$relativeTo, [string]$path){
        <#
        Returns the relative path from one path to another.
        Params
        ======
        - $relativeTo [string] The source path relative to the result. This path is always treated as a directory.
        - $path [string] Target path.
        Returns
        =======
        [string] Relative path, or path if the paths do not share the same root.
        Exceptions
        ==========
        - [ArgumentNullException] The value of $relativeTo or $path is null。
        - [ArgumentException] $relativeTo or $path is actually null.
        #>
        return [System.IO.Path]::GetRelativePath($relativeTo, $path)
    }
    static [string[]] get_items([string]$path){
        <#
        Get all subprojects in the specified directory. 
        Params
        ======
        - $path [string] The path value represented by a string.
        - $sift [string] Optional, used to indicate the filtered content.
          * When the parameter value is' file', only the absolute path of 
            the files in it will be returned.
          * When the parameter value is' folder', the absolute path of the 
            directory (folder) in it is returned.
        Notes
        =====
          This method only gets the current level of subdirectories, while 
          the folders containing subdirectories will not be traversed.
          If you need to recursively obtain all descendants directories, 
          you should consider using `get_descendants()` method instead.
        #>
        $item_obj = Get-ChildItem $path |  Sort-Object
        $ary = [ArrayList]::new()
        foreach ($item in $item_obj){
            $ary.Add($item.ToString())
        }
        return $ary
    }
    static [string[]] get_items([string]$path, [string]$sift){
        if($sift -eq 'file'){
            $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
            $ary = [ArrayList]::new()
            foreach ($item in $files){
                $ary.Add($item.ToString())
            }
            return $ary
        }elseif ($sift -eq 'folder') {
            $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
            $ary = [ArrayList]::new()
            foreach ($item in $folders){
                $ary.Add($item.ToString())
            }
            return $ary
        }else{
            $item_obj = Get-ChildItem $path |  Sort-Object
            $ary = [ArrayList]::new()
            foreach ($item in $item_obj){
                $ary.Add($item.ToString())
            }
            return $ary
        }
    }
    static [string[]] get_descendants([string]$path){
        <#
        Get all items in the specified directory, and recursively traverse all descendant folders.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $sift [string] Optional, used to indicate the filtered content.
          * When the parameter value is' file', only the absolute path of the files in it will be returned.
          * When the parameter value is' folder', the absolute path of the directory (folder) in it is returned.
        #>
        $ary = [ArrayList]::new();
        $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
        foreach ($item in $item_obj){
            if([Path]::is_dirname($item)){
                $sub_ary = [Path]::get_descendants($item);
                $ary.AddRange($sub_ary);
            }
            else{
                $ary.Add($item);
            }
        }
        return $ary
    }
    static [string[]] get_descendants([string]$path, [string]$sift){
        $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
        $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
        $ary = [ArrayList]::new()
        # only file
        if($sift -eq 'file'){
            if($null -ne $files){
                foreach ($file in $files){
                    $ary.Add($file)
                }
            }
            foreach ($item in $folders){
                $ary.AddRange([Path]::get_descendants($item,'file'))
            }
        }
        # only dir
        elseif ($sift -eq 'folder') {
            if($null -ne $folders){
                foreach ($item in $folders){
                    $ary.Add($item);
                    $ary.AddRange([Path]::get_descendants($item,'folder'))
                }
            }
        }
        # all
        else{
            $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
            foreach ($item in $item_obj){
                if([Path]::is_dirname($item)){
                    $sub_ary = [Path]::get_descendants($item);
                    $ary.AddRange($sub_ary);
                }
                else{
                    $ary.Add($item);
                }
            }
        }
        return $ary
    }
    static [string[]]filter_files([string]$path, [string]$sub_string){
        <#
        Filter the files containing the specified string from the specified directory.
        Params
        ======
        - $path [string] 
        - $sub_string [string] 
        - $recursion [bool] Recursively search all descendant directories, defaulf $False
        #>
        $ary = [ArrayList]::new();
        foreach ($item in [Path]::get_items($path,'file')) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){
        $ary = [ArrayList]::new();
        if($recursion){
            $all = [Path]::get_descendants($path,'file')
        }else{
            $all = [Path]::get_items($path,'file')
        }
        foreach ($item in $all) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_dirs([string]$path, [string]$sub_string){
        $ary = [ArrayList]::new();
        foreach ($item in [Path]::get_items($path,'folder')) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){
        $ary = [ArrayList]::new();
        if($recursion){
            $all = [Path]::get_descendants($path,'folder')
        }else{
            $all = [Path]::get_items($path,'folder')
        }
        foreach ($item in $all) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [System.DateTime]get_modify_time([string]$path){
        <#
        Returns the last modification time of a file or directory.
        Params
        ======
        - $path [string] The path value represented by a string.
        #>
        return [System.IO.DirectoryInfo]::new($path).LastWriteTime
    }
    static [bool]is_dirname([string]$path){
        <#
        Specifies whether the path represents a folder.
        Params
        ======
        - $path [string] The path value represented by a string.
        Returns
        =======
         - $True  If the specified path represents a folder
         - $False Versa
        Notes
        =====
          In most cases, you can also use the command: 
          `Test-Path -Path $path -PathType leaf `, 
          However, using the `Test-Path` command can't deal with 
          the case that the file name contains "[" as the powershell 
          compiler will throw back an error in this case.
        #>
        return [Path]::has_attributes($path,"Directory")
    }
    static [bool]is_filename([string]$path){
        <#
        Returns whether the specified path value represents a file.
        Params
        ======
        - $path The path value represented by a string.
        Notes
        =====
          In most cases, you can also use the command: 
          `Test-Path -Path $path -PathType leaf `, 
          However, using the `Test-Path` command can't deal with 
          the case that the file name contains "[" as the powershell 
          compiler will throw back an error in this case.
        #>
        return -not [Path]::has_attributes($path,"Directory")
    }
    static [bool]is_newer_than($path, $time){
        <#
        Test whether the time of a file is before the specified date.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $time A point-in-time string, such as "July 13, 2009"
        Returns
        =======
        - $True  If the modification time of the specified file is newer than this point in time;
        - $False Versa。
        #>
        return Test-Path -Path $path -NewerThan $time
    }
    static [bool]is_empty([string]$path){
        <#
        The folder is not empty, or the specified path is a file.
        Params
        ======
        - $path [string] The path value represented by a string.
        Retuens
        =======
        - $True  Folder is empty.
        - $False The folder is not empty, or the specified path is a file.
        #>
        if([Path]::is_dirname($path)){
            if((Get-ChildItem $path).count -eq 0){
                return $True
            }
            else{
                return $False
            }
        }
        else{
            write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. "
            return $False
        }
    }
    static [bool]is_abs([string]$path){
        <# 
        Determine whether the path value represents an absolute path.
        Params
        ======
        - $path [string] The path value represented by a string.
        Retuens
        =======
        - $True  Is an absolute path.
        - $False Versa.
        #>
        return Split-Path -Path $path -IsAbsolute
    }
    static [string[]]get_attributes([string]$path){
        <#
        Gets the operator of attribute description of the directory.
        #>
        return [System.IO.File]::GetAttributes($path).ToString().Split(", ")
    }
    static [bool]has_attributes([string]$path, [string]$attributes){
        <#
        Returns whether the file or directory contains an attribute descriptor.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $attributes [string] Represents an attribute descriptor of a directory. The value of $attributes could be:
            * Archive 此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。
            * Compressed 此文件是压缩文件。
            * Device 留待将来使用。
            * Directory 此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。
            * Encrypted 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。
            * Hidden 文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。
            * IntegrityStream 文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。
            * Normal 该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。
            * NoScrubData 文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。
            * NotContentIndexed 将不会通过操作系统的内容索引服务来索引此文件。
            * Offline 此文件处于脱机状态, 文件数据不能立即供使用。
            * ReadOnly 文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。
            * ReparsePoint 文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。
            * SparseFile 此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。
            * System 此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。
            * Temporary 文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。
        Retuens
        =======
        - $True  Includes.
        - $False Not includes.
        #>
        return [Path]::get_attributes($path).Contains($attributes)
    }
    static [int64]$counter;
    static [int64]get_size([string]$path){
        <#
        Returns the file size, or an error if the file does not exist.
        Params
        ======
        - $path [string] The path value represented by a string.
        #>
        [Path]::counter = -1;
        return [Path]::get_size($path,[Path]::counter)
    }
    static [int64]get_size([string]$path,[string]$ParentId){
        $count_size = 0;
        $file_infos = Get-ChildItem $path;
        # If it is a file, directly return the file size.
        if($file_infos.Attribute -eq 'Archive'){
            write-host $path+" is a file."
            $count_size = $count_size + $file_infos.Length;
        }
        # If it is a directory, the total size is calculated recursively.
        else{
            $count = $file_infos.Count;
            for ($i = 0; $i -lt $file_infos.Count; $i++) {
                $child = $file_infos[$i];
                [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately.
                $ID = [Path]::counter;
                # If it is a file, the size is accumulated.
                if([Path]::is_filename($child)){
                    $count_size =  $count_size + $child.Length;
                }
                # If it is a directory, continue to recursively accumulate the size.
                else{
                    $count_size =  $count_size + [Path]::get_size($child,$ID)
                }
                # Progress bar display
                $percent = $i / $count;  # Calculate the percentage by subentry.
                if($ParentId -eq -1){
                    Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
                }else{
                    Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
                }
            }
        }
        return $count_size
    }
    static [string]join($path, $childpath){
        <# 
        Connect the directory and file name into a path.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $childpath [string] childpath path value represented by a string.
        #>
        return Join-Path -Path $path -ChildPath $childpath
    }
    static [string[]]split([string]$path){
        <#
        Divide the path into two parts: dirname and basename.
        Params
        ======
        - path [string] The path value represented by a string.
        Returns
        =======
        - $dirname   The absolute path of the folder.
        - $basename  Subfile or subdirectory name
        #>
        $dirname = Split-Path -Path $path -Leaf;
        $basename = Split-Path -Path $path;
        return $dirname,$basename
    }
    static [string[]]get_enviroment(){
        return [Environment]::GetEnvironmentVariable('Path', 'Machine')
    }
    static [void]set_enviroment($path){
        [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
    }
    static [void]set_enviroment($path,$env_var_target){
        if($env_var_target -eq 'Machine'){
            [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
        }
        elseif($env_var_target -eq 'User'){
            [Environment]::SetEnvironmentVariable('Path', $path,'User')
        }
        else{
            write-host -ForegroundColor Red "ValueError: The value of variable  `"`$env_var_target`" can only be one of 'Machine' or 'User'." 
        }   
    }
    static [void]delete([string]$path){
        <#
        Delete the file or directory corresponding to the specified path.
        Params
        ======
        - path [string] The path value represented by a string.
        #>
        Remove-Item $path;
    }
    static [void]make($path){
        <#
        Create a series of folders according to the given path.
        Params
        ======
        - path [string] The path value represented by a string.
        #>
        New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" 
    }
}

附录2: 脚本位置

方式一: Get-Location

你可以使用如下方式获取脚本所在目录的位置:

(Get-Location).Path

当你使用一个bat来调用一个包含这种方式作为BASE_DIR来使用时往往是正确的,但是如果你将这个样的bat添加到Windwos任务计划中,BASE_DIR将成为cmd.exe所在文件夹。

方式二: 使用$MyInvocation

你可以通过以下方式在ps1脚本中表示自己的脚本所在位置:

$MyInvocation.MyCommand.source

因此脚本所在文件夹的绝对路径所在位置可以表示为:

using module .\utils\jcpath.psm1
[Path]::get_dirpath($MyInvocation.MyCommand.source)
目录
相关文章
|
3月前
|
存储 运维 应用服务中间件
[运维日志] Web 服务器日志依日期归档(Powershell 实现,附源代码)
[运维日志] Web 服务器日志依日期归档(Powershell 实现,附源代码)
74 0
|
3月前
|
运维 Linux Windows
[运维技术]PowerShell中实现一个最基本的日志器logger
[运维技术]PowerShell中实现一个最基本的日志器logger
37 1
|
7月前
|
存储 JSON 运维
PowerShell / 运维PowerShell 对象的序列化和反序列化
本文介绍Powershell中如何实现对象的序列化和反序列化。
82 0
|
3月前
|
运维 Linux 网络安全
利用群晖NAS+shell脚本实现运维命令执行结果文件自动上传
利用群晖NAS+shell脚本实现运维命令执行结果文件自动上传
128 0
|
3月前
|
存储 运维 Shell
运维:Powershell面向对象编程简介
运维:Powershell面向对象编程简介
43 1
|
3月前
|
存储 JSON 运维
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
51 0
|
3月前
|
运维 自然语言处理 API
[运维]PowerShell简体中文编码转换
[运维]PowerShell简体中文编码转换
47 0
|
3月前
|
存储 运维 JavaScript
[运维笔记] PowerShell (模块).模块的查找、安装、卸载、更新、保存、发布
[运维笔记] PowerShell (模块).模块的查找、安装、卸载、更新、保存、发布
92 0
|
3月前
|
运维
[运维笔记] PowerShell (模块).模块清单
[运维笔记] PowerShell (模块).模块清单
28 0
[运维笔记] PowerShell (模块).模块清单
|
8月前
|
运维 Shell Python
【运维知识高级篇】超详细的Shell编程讲解2(变量切片+统计变量长度+字串删除+字串替换+七种方法进行数值运算+整数比较+多整数比较+文件判断+字符串比对+正则比对+配合三剑客的高阶用法)(一)
【运维知识高级篇】超详细的Shell编程讲解2(变量切片+统计变量长度+字串删除+字串替换+七种方法进行数值运算+整数比较+多整数比较+文件判断+字符串比对+正则比对+配合三剑客的高阶用法)
91 0